Archived

This topic is now archived and is closed to further replies.

VB and C++ Classes in DLL's

This topic is 6354 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Yeah, Yeah, Yeah, I know. Why would I want to do a thing like that. Well, I''m working on a project that a VB programmer friend of mine started. It''s an online RPG type thing and he''s doing Client/Server. My job is to make the graphics engine that it''ll use. So far we''ve had a bit of success useing an ActiveX control but that really isn''t cutting it anymore and I need a better way. So I though if I could expose some classes from my C++ DLL to a VB module I could get rolling again. Problem is I have no idea how to nor if it''s even possible. I''ve heard that VB''s ActiveX DLL can, but I don''t know what it is really nor do I know how to make one from MSVC if it''s even possible. I''m open to any and all suggestions. Thanks in advance.
~Tim the Enchanter~ Arthur: Ohh great enchanter, tell us, what is your name? Enchanter: Some call me Timmmmmm. Arthur: Tell us great enchanter, how to you make fire without flint and tinder? Enchanter: Silence! Monty Python:The Search For The Holy Grail

Share this post


Link to post
Share on other sites
Hello...Tim..
Maybe I can answer your question. To use c++ .dlls with your visual basic engine I would suggest using COM (yah it sucks I know.) Component Object Model is what COM stands for if I''m not mistaken. What you end up doing is creating a component that implements interfaces. In your case you would be using a C++ class to make the component.
The dll will allow your VB program to create the component and then query for the interfaces you have defined. It is really a complex topic so I would suggest getting InsideCOM from Microsoft press. It goes over this exact thing. But basically onceyou have the component in the dll what you do is ask the dll to create the component. It will then do so and the next thing to do is to query that component for the specific interfaces that you need.


Random Task

Share this post


Link to post
Share on other sites
Actually, you could just compile your class into a normal C++ DLL, and in VB you go to Project-Refrences, then hit Browse, and select your DLL. Should be smooth riding from there. Tell me if this works, by the way. I''ve never tried doing it with my C++ classes b4.

Share this post


Link to post
Share on other sites
Thanks a million RandomTask and BeanDog. I never would have thought to goto a COM DLL. It seems that a COM DLL either acts just like or is the same thing as a VB ActiveX DLL.

I''ve got the DLL working so far and once I compile it I can just reference to it in VB after it''s been registered. Any DLL that contains TypeLibrary or whatever information can be referenced like that, but if you make a normall DLL with no TypeLibrary info then you can''t use it in VB. Believe me I tried, and I am still trying. I would like to put TypeLibrary info into a normal DLL I just don''t know how to expose an object with the ODL language.

This way I could do a conditional compilation with a static test container so I can debug with ease. I''m sure I can do this using the COM DLL code an lots of #ifdef stuff, but I would like just basic object declarations. So I can say Dim file As CSTDFile instead of Dim file as TESTLib.STDFile and so on. Plus COM DLL''s seem to be really picky about linking. If I link to one of my static libs by just adding it to the FileView it''ll work with a Debug Build but not a Release, but if I add the lib into the link tab in the project settings I''m ok. Anyways, if anyone knows how to generate an ODL file for a normal DLL it''d make my life a bit easier. Elsewise COM it is.

Thanks


~Tim the Enchanter~
Arthur: Ohh great enchanter, tell us, what is your name?
Enchanter: Some call me Timmmmmm.
Arthur: Tell us great enchanter, how to you make fire without flint and tinder?
Enchanter: Silence!

Monty Python:The Search For The Holy Grail

Share this post


Link to post
Share on other sites
Ok I goofed a bit. There is no way to export classes directly without using COM/ActiveX. ODL compleetely threw me off guard, I thought it was a way to directly expose classes but it''s just a part of ActiveX. I''m still a bit confused, but I''m better now.


~Tim the Enchanter~
Arthur: Ohh great enchanter, tell us, what is your name?
Enchanter: Some call me Timmmmmm.
Arthur: Tell us great enchanter, how to you make fire without flint and tinder?
Enchanter: Silence!

Monty Python:The Search For The Holy Grail

Share this post


Link to post
Share on other sites
VB ActiveX DLLs are actually COM DLLs, but I have it on a reasonably good authority that the implementation by Microsoft isn''t so hot...

As an example, write a method called AddRef, QueryInterface or Release in a class module - then try and run it....

Basically VB has reserved these method names because it uses them to expose the necessary COM stuff.

Writing a COM DLL using C++ specifically intended for VB is quite tricky if you want to do it yourself from scratch. You need to pay particular attention to a couple of interfaces - IUnknown and IDispatch (yuk).

Better off using something like ATL.

Share this post


Link to post
Share on other sites
Thanks TPH. I''ve got it working ok now, fixed the link problems. I"m using the type of COM DLL that Appwizzard makes, I belive that''s ALT but thanks to MSDev I don''t have to worry about that much because it''s hidden behind ClassView.

This is a lot easier than I thought. I was thinking I would have to maintain a lot of crap manually.


~Tim the Enchanter~
Arthur: Ohh great enchanter, tell us, what is your name?
Enchanter: Some call me Timmmmmm.
Arthur: Tell us great enchanter, how to you make fire without flint and tinder?
Enchanter: Silence!

Monty Python:The Search For The Holy Grail

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

There is nothing wrong with VB ActiveX DLLS, especially for logic code. Its a hell of alot faster than alot of people give it credit for.

If down the road you run into a speed issue, then you can implement the object in C++ and likely have a drop in replacement for the original if you follow the same signatures.

Besides, there will be a bit of container functionality you will get for free coming from VB instead of C++ (collection/dictionary support).

Since it sounds like your already headed down the C++ path, stick with ATL as it does make COM development extremely easy compared to a raw COM implementation in C++.



Share this post


Link to post
Share on other sites
Ok this is a bit odd. I''ve got MSVC exporting my class as an object and Visual Basic can see it just fine, but I''ve also created a control in the same DLL that''s intended to replace an ActiveX OCX and it''s not working.

The OCX control has the same members as the DLL one, but the DLL one fails whenever I try to call any of it''s functions. Even if all the function does is return S_OK.

I''m compleetely clueless why VB dosen''t like my Controls. Am I forgeting something that''s specific to the VB interface?

I know that this is a long shot, but if anyone has any idea what I''m doing wrong I''d be beyond thankfull.


~Tim the Enchanter~
Arthur: Ohh great enchanter, tell us, what is your name?
Enchanter: Some call me Timmmmmm.
Arthur: Tell us great enchanter, how to you make fire without flint and tinder?
Enchanter: Silence!

Monty Python:The Search For The Holy Grail

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

I am assuming that the DLL houses a COM object so what is the Err.Descpription or Err.Number after you try to use the object?

Using ATL to create COM objects in C++ then using the object from VB is a snap, once you get the hang of it.

From your ATL project (C++) have you inserted your new object? (Insert | Insert new ATL object ...). This process is bascially just adding a C++ class that will implement your COM interface that will be used from VB (After adding a Reference to it).



Share this post


Link to post
Share on other sites
First of all thanks.

Secondly ATL is a sensitive little bugger.

Finally I think I''ve got it all solved(for now).

Apparently ATL get''s pissy if you delete an object or control from the project, else I''m not doing it right. And there''s no Remove Object, gee thanks.

I''m adding all of the objects properly but when I delete them then recreate to make major changes(Object->Control), ATL will compile it and say alls fine an dandy but Visual Basic won''t "see" it properly. I can solve this by recreating the entire project, not good nor fun.

I''m slowly getting the hang of this. It''s not that though, then I decide to delete something and well that''s a painfull memory.

Is there any good way to delete objects from a project?

Once again Thanks.


~Tim the Enchanter~
Arthur: Ohh great enchanter, tell us, what is your name?
Enchanter: Some call me Timmmmmm.
Arthur: Tell us great enchanter, how to you make fire without flint and tinder?
Enchanter: Silence!

Monty Python:The Search For The Holy Grail

Share this post


Link to post
Share on other sites
Guest Anonymous Poster




There is no simple "Remove Object" command...much as I wish there was. To remove an object you need to:

- manually remove files (.h/.cpp) from project
- remove objects reference from DLL OBJECT_MAP
- remove reference from .idl file
- rebuild all



    

//: DLL .cpp file

BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_CallCOM, CCallCOM) //: <-- delete line

END_OBJECT_MAP()
[/source]


[source]
// test.idl : IDL source for test.dll

//


// This file will be processed by the MIDL tool to

// produce the type library (test.tlb) and marshalling code.

import "oaidl.idl";
import "ocidl.idl";

//: to remove ICallCOM object remove from here ...

//: -----------------------

[
object,
uuid(803CFFCE-5E21-11D4-9E8F-00B0D01A8529),
dual,
helpstring("ICallCOM Interface"),
pointer_default(unique)
]
interface ICallCOM : IDispatch
{
[id(1), helpstring("method DoSomething")] HRESULT DoSomething();
};

//: -----------------------

//: <-- to here

[
uuid(803CFFC1-5E21-11D4-9E8F-00B0D01A8529),
version(1.0),
helpstring("test 1.0 Type Library")
]
library TESTLib
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");

[
uuid(803CFFCF-5E21-11D4-9E8F-00B0D01A8529),
helpstring("CallCOM Class")
]

//: remove coclass CallCOM

//: -----------------------

coclass CallCOM
{
[default] interface ICallCOM;
};
//: -----------------------


};




It helps to understand .idl. Luck!

Share this post


Link to post
Share on other sites
Whoa thanks, that''ll make my life a lot easier. I wasn''t expecting to see code . This is great, I''ve gotten more help out of this forum than I thought I would.

Everything''s working Ok now, but I have one last thought. Currently I''ve got my Object useing callbacks by stealing pointers to Visual Basic functions. This is working just fine(although if I forget to specify ByVal Visual Basic will crash).

I''m currious if there''s a better way to do this. I was thinking Events but Visual Basic seems to only be able to see Events from Controls that are on the forms. I made a new Object and gave it a Method that Fired an Event via ConnectionPoint(s), however, If I say "Dim test As New TestLib.test" I can use the Methods but not the Events.

I could just use an invisible Control and all that, but that would defeat my purpose. I''m just trying to do it to see if I can do it and how. To see what I can get Visual Basic to do. This COM thing is starting to get really interesting. Anyways, correct me if I''m wrong, but Object Events aren''t useable in Visual Basic right?

Thanks for all of the Help, hopefully I''ve got it all down now.


~Tim the Enchanter~
Arthur: Ohh great enchanter, tell us, what is your name?
Enchanter: Some call me Timmmmmm.
Arthur: Tell us great enchanter, how to you make fire without flint and tinder?
Enchanter: Silence!

Monty Python:The Search For The Holy Grail

Share this post


Link to post
Share on other sites
Guest Anonymous Poster


I am in class right now so I have a little free time to post more often...

You can create an ATL DLL that is an event source and then sink the events from VB. That way, within your ATL DLL you can fire the event and VB should catch it...however you have to dim your VB variable "WithEvents".

When you create your ATL object, check where you want to support "connection points". You will notice a class with an underscore ("_") in front of it..this is your event source..add "methods" to it...they become events.

An easier method might be using an "interface callback", what this means is that you "register" (advise/unadvise) another interface that is used as your "messenger" or communication method between your client and server pieces...this works well inprocess, but takes more work for out of process if I remember.

You can try searching Microsofts site for "interface callbacks" and it should turn up an article that will help.

Share this post


Link to post
Share on other sites
Oh my gosh, thank you. I never would have event thought, WithEvents, not even my Visual Basic programmer friend that I''m working with on the project knew about that. How do you know all of this? College? I''ve was in a programming class my last year of high school and it was a joke. If that''s the sort of programmin knowledge that college provides them I just can''t wait till I start.

Again, thanks a lot.


~Tim the Enchanter~
Arthur: Ohh great enchanter, tell us, what is your name?
Enchanter: Some call me Timmmmmm.
Arthur: Tell us great enchanter, how to you make fire without flint and tinder?
Enchanter: Silence!

Monty Python:The Search For The Holy Grail

Share this post


Link to post
Share on other sites
Guest Anonymous Poster


I have several years experience doing multi-language development for the business world [I can here all of you shuddering as you read this...]....

C++ to VB, C++ to VBScript, C++ to Visual FoxPro, C++ to Lotus Notes...you pick up a few tricks along the way.

Thanks for the compliment, but the truth is, there are quite a few people on this site who are a lot sharper than I am and they are probably half my age!

All of what we have talked about above would have been even simpler to do in straight VB, with ActiveX DLLs. WithEvents isn''t necessarily a "trick" as its fairly well documented..but it might seem arcane coming from C++.

-Z

Share this post


Link to post
Share on other sites