🔒 Locked
library dll
Advertisement
Original Post
ok, iv e figured out how to access a c++ dll function from VB using the declare statement.
however, this method is extremely limiting... i need to be able to add a refrence to the dll from the refrences menu. however, vb says my dll cannot be added. How do I create a vb compatible dll in vc++?
right now, in my non-mfc dll, i use _stdcall to write functions and i add them in a .def file...
what else do i needa do?
pulease!!! i needa figure this badly!
any help appreciated
You need to create a ATL COM dll, this will then be available from the References menu in vb.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ok, the alt com dll....
i made a project with this and its sorta complicated, and im pretty sure that mfc is in works.
bascially, there is a altcomdll.cpp, .idl, and .def. .
so, what do i need to do to add functions to export?
i tried adding a .cpp file, and added export names to the .def file, but i got the error: "unexpected end of file." when i compiled it...
ok, the alt com dll....
i made a project with this and its sorta complicated, and im pretty sure that mfc is in works.
bascially, there is a altcomdll.cpp, .idl, and .def. .
so, what do i need to do to add functions to export?
i tried adding a .cpp file, and added export names to the .def file, but i got the error: "unexpected end of file." when i compiled it...
Yeah, the reference list in VB is really a list of the registered COM libraries installed on the system.
"Inside COM Base Services" takes you through all the basic issues of COM, but it doesn't cover much of the ATL. There's a book published by Wrox (mostly red cover, yellow lettering) called "Inside the ATL" or "COM Programing with the ATL" that focuses on the ATL.
Making a COM dll that can be used in VB is *huge* P-I-T-A. You are severely limited on the varible types that you can use - and must use SAFEARRAYs no C pointer arrays because you can't use any pointers! No unsigned types are allowed either. And you have to use all ole/wide/unicode strings or B-strings.
Don't mess with the .def file or add any .cpp's of your own.
I've been thinking about writing a tutorial on this for a while, so here goes it:
**************************************************
Magmai Kai Holmlor's
Crude & Rude $0.05 ATL 3.x Tutorial
(You get what you pay for)
1) An ATL Project
Start MSVC6
File->New->Projects->ATL COM AppWizard
Name the Project, "ATLTut" will work just fine
Click OK
Sever Type: Dynamic Link Library (DLL)
Do NOT check "Allow merging...", nor "Support MFC", nor "Support MTS"
Click Finish
Click OK
2) A New Component
Go to the ClassView (should be the default)
Right-click “ATLTut classes”
Choose "New ATL Object"
Choose "Simple Object"
Click Next
Give it a Short Name, "COMVirgin" is good (DONT CLICK NEXT)
Goto the Attributes page first
Select "Both" for the Threading Model and "Custom" for the Interface
Whatever you twiddle, do NOT check "Free Threaded Marshaler" (some day you may want to, for instance if you make a DirectShow filter using the ATL you could safely use the FTM since you are already required to deal with all the issues of free-threading)
(You can disable aggregation if you want to be like the DirectX pricks, and choose the Free threading model if you like life on the edge)
Click OK
Congratulations you've just declared your first COM object
3) Sanity Check
Now (try) to compile it
If you get an error like “Cannot open include file: 'xmldom.idl'” it is because you installed some of the latest Platform SDK but decide you needn’t need some of the internet crap. You can be an xml-hating-bigot like me and just comment the imports out, or go through the hassle of installing the entire Platform SDK (the web version of which is broken at the time of this writing [it started working again a few days ago 12/14/01]) – we won’t be doing anything with them here so it doesn’t matter.
If it doesn’t compile and you can’t figure it out, search the board for the specific compiler/linker error and see what other people did to fix it. Failing that, let everyone know how clueless you are and ask for help (not to worry once-upon-a-time I didn’t know either). Be sure to write the error number, whether it was a linker or a compiler error and maybe even give a few lines of code around it
6) A Method of My Own
Go back to the ClassView
Right-click ICOMVirgin (the thing with the bubble wand)
Choose “Add Method”
Name your method, how about “Deflower”
For the Parameter string, type this in “[out, retval] long* pVal”
Do NOT change the Return Type, it should *always* be an HRESULT
Expand the CCOMVirgin
Expand the nested ICOMVirgin
Double click Deflower(long *pVal) (the _purple one *not* the green one)
Where it says “// TODO: Add your implementation code here” put “*pVal = 42;”
Compile
Well, that’s it, you’ve just made an in-process COM server (aka a COM dll)
Now that we have our COMponent ready to go, we need to find a host for it
Most of the questions are about how to make a COM dll in C++ and use it in VB. I don’t have VB installed on my computer so I’m going to use Excel.
7) Find an Unsuspecting Host
Start Excel
Tools->Macros->Record New Macro->OK
Click the Stop button
Click Tools->Macros->Visual Basic Editor
Click Tools->References
Browse down to, and check “ATLTut 1.0 Type Library”
Click OK
Browse to Module1 under Modules
Enter this inside the subroutine:
Dim pCOMVirgin as ATLTUTLib.COMVirgin
Set pCOMVirgin = New ATLTUTLib.COMVirgin
MsgBox (pCOMVirgin.Deflower)
Run it
Assuming all the pegs & holes lined up you’re no longer a COM virgin!
Atl 7) The Usual Suspect
From MSVC6,
Project->Add To Project->New
Projects Tab->Win32 Console App. (K.I.S.S.)
Name the project (say, COMVirginHost)
Make it a “Simple Application” so we don’t have to mess around with main (Finish, OK)
Browse to the source file in the FileView, “COMVirginHost.cpp” in my case
Compile
(These are optional steps, but to a neat effect)
Right-Click ‘Header Files’
Choose “Add Files to Folder”
Browse to “.\COMVirginHost\Debug\”
Choose “ATLTut.tlh”
This makes your interface appear in the ClassView of the new project, and enables the code completion feature with it
(End optional steps)
Rather than tell you want to type, make it look like this
Compile & Run!
Note that in C++ we have the option of calling spCOMVirgin->raw_Deflower which returns an HRESULT and takes a long* or we can call the VB-like wrapper without the raw prefix. This is *extremely* useful in cases that you anticipate failure or when the failure code determine what you do next. If the code fails with the wrapper, it will throw a _com_error exception, the same thing causes a run-time error in VB.
CComPtr creates an ATL smart pointer to our COMVirgin interface. (If the code completion doesn’t work with the smart pointer, don’t ask me, I don’t understand it either. It works on half of my projects, but not the other half.)
The #import directive is an MS extension (albeit a kick-ass one) that lets you import type-library information into a C++ project as easily as a VB reference
The "ATLTUTLib" namespace comes from the Library statement in the .idl file of the COM dll project. So if you can change that if you want.
Magmai Kai Holmlor
- Not For Rent
[edit]
Fixed the mistake in step 7 that MonkeyChuff (eheheh) pointed out
Fixed some typos
Added ATL/C++ host example
Edited by - Magmai Kai Holmlor on October 15, 2001 12:14:43 AM
Edited by - Magmai Kai Holmlor on December 14, 2001 8:21:08 PM
"Inside COM Base Services" takes you through all the basic issues of COM, but it doesn't cover much of the ATL. There's a book published by Wrox (mostly red cover, yellow lettering) called "Inside the ATL" or "COM Programing with the ATL" that focuses on the ATL.
Making a COM dll that can be used in VB is *huge* P-I-T-A. You are severely limited on the varible types that you can use - and must use SAFEARRAYs no C pointer arrays because you can't use any pointers! No unsigned types are allowed either. And you have to use all ole/wide/unicode strings or B-strings.
Don't mess with the .def file or add any .cpp's of your own.
I've been thinking about writing a tutorial on this for a while, so here goes it:
**************************************************
Magmai Kai Holmlor's
Crude & Rude $0.05 ATL 3.x Tutorial
(You get what you pay for)
1) An ATL Project
Start MSVC6
File->New->Projects->ATL COM AppWizard
Name the Project, "ATLTut" will work just fine
Click OK
Sever Type: Dynamic Link Library (DLL)
Do NOT check "Allow merging...", nor "Support MFC", nor "Support MTS"
Click Finish
Click OK
2) A New Component
Go to the ClassView (should be the default)
Right-click “ATLTut classes”
Choose "New ATL Object"
Choose "Simple Object"
Click Next
Give it a Short Name, "COMVirgin" is good (DONT CLICK NEXT)
Goto the Attributes page first
Select "Both" for the Threading Model and "Custom" for the Interface
Whatever you twiddle, do NOT check "Free Threaded Marshaler" (some day you may want to, for instance if you make a DirectShow filter using the ATL you could safely use the FTM since you are already required to deal with all the issues of free-threading)
(You can disable aggregation if you want to be like the DirectX pricks, and choose the Free threading model if you like life on the edge)
Click OK
Congratulations you've just declared your first COM object
3) Sanity Check
Now (try) to compile it
If you get an error like “Cannot open include file: 'xmldom.idl'” it is because you installed some of the latest Platform SDK but decide you needn’t need some of the internet crap. You can be an xml-hating-bigot like me and just comment the imports out, or go through the hassle of installing the entire Platform SDK (the web version of which is broken at the time of this writing [it started working again a few days ago 12/14/01]) – we won’t be doing anything with them here so it doesn’t matter.
If it doesn’t compile and you can’t figure it out, search the board for the specific compiler/linker error and see what other people did to fix it. Failing that, let everyone know how clueless you are and ask for help (not to worry once-upon-a-time I didn’t know either). Be sure to write the error number, whether it was a linker or a compiler error and maybe even give a few lines of code around it
6) A Method of My Own
Go back to the ClassView
Right-click ICOMVirgin (the thing with the bubble wand)
Choose “Add Method”
Name your method, how about “Deflower”
For the Parameter string, type this in “[out, retval] long* pVal”
Do NOT change the Return Type, it should *always* be an HRESULT
Expand the CCOMVirgin
Expand the nested ICOMVirgin
Double click Deflower(long *pVal) (the _purple one *not* the green one)
Where it says “// TODO: Add your implementation code here” put “*pVal = 42;”
Compile
Well, that’s it, you’ve just made an in-process COM server (aka a COM dll)
Now that we have our COMponent ready to go, we need to find a host for it
Most of the questions are about how to make a COM dll in C++ and use it in VB. I don’t have VB installed on my computer so I’m going to use Excel.
7) Find an Unsuspecting Host
Start Excel
Tools->Macros->Record New Macro->OK
Click the Stop button
Click Tools->Macros->Visual Basic Editor
Click Tools->References
Browse down to, and check “ATLTut 1.0 Type Library”
Click OK
Browse to Module1 under Modules
Enter this inside the subroutine:
Dim pCOMVirgin as ATLTUTLib.COMVirgin
Set pCOMVirgin = New ATLTUTLib.COMVirgin
MsgBox (pCOMVirgin.Deflower)
Run it
Assuming all the pegs & holes lined up you’re no longer a COM virgin!
Atl 7) The Usual Suspect
From MSVC6,
Project->Add To Project->New
Projects Tab->Win32 Console App. (K.I.S.S.)
Name the project (say, COMVirginHost)
Make it a “Simple Application” so we don’t have to mess around with main (Finish, OK)
Browse to the source file in the FileView, “COMVirginHost.cpp” in my case
Compile
(These are optional steps, but to a neat effect)
Right-Click ‘Header Files’
Choose “Add Files to Folder”
Browse to “.\COMVirginHost\Debug\”
Choose “ATLTut.tlh”
This makes your interface appear in the ClassView of the new project, and enables the code completion feature with it
(End optional steps)
Rather than tell you want to type, make it look like this
|
Compile & Run!
Note that in C++ we have the option of calling spCOMVirgin->raw_Deflower which returns an HRESULT and takes a long* or we can call the VB-like wrapper without the raw prefix. This is *extremely* useful in cases that you anticipate failure or when the failure code determine what you do next. If the code fails with the wrapper, it will throw a _com_error exception, the same thing causes a run-time error in VB.
CComPtr creates an ATL smart pointer to our COMVirgin interface. (If the code completion doesn’t work with the smart pointer, don’t ask me, I don’t understand it either. It works on half of my projects, but not the other half.)
The #import directive is an MS extension (albeit a kick-ass one) that lets you import type-library information into a C++ project as easily as a VB reference
The "ATLTUTLib" namespace comes from the Library statement in the .idl file of the COM dll project. So if you can change that if you want.
Magmai Kai Holmlor
- Not For Rent
[edit]
Fixed the mistake in step 7 that MonkeyChuff (eheheh) pointed out
Fixed some typos
Added ATL/C++ host example
Edited by - Magmai Kai Holmlor on October 15, 2001 12:14:43 AM
Edited by - Magmai Kai Holmlor on December 14, 2001 8:21:08 PM
Thats a good consise tutorial, the only thing being in point 7 to use the pComVirgin you need to reference the COM object from Tools .. References.
Or create it thus .
Dim pComVirgin As Object
Set pComVirgin = CreateObject("ATLTutLib.ComVirgin")
MsgBox pComVirgin.Deflower
This method is late bound and doesn''t require the object to be referenced before use. The only down side is you don''t get the popup list of methods after you type a period, the reason being it uses it IDispatch interface and GetIDsFromName (all in the background), where as the referenced version shown in point 7 uses IUnknown and the VTable.
Or create it thus .
Dim pComVirgin As Object
Set pComVirgin = CreateObject("ATLTutLib.ComVirgin")
MsgBox pComVirgin.Deflower
This method is late bound and doesn''t require the object to be referenced before use. The only down side is you don''t get the popup list of methods after you type a period, the reason being it uses it IDispatch interface and GetIDsFromName (all in the background), where as the referenced version shown in point 7 uses IUnknown and the VTable.
OK...
it says that its not allowed to pass function pointers in the syntax of : void (*f)()
is there a different syntax, or is there a way to force this?
i really want to get/pass function pointers to vb...
i can do it using normal dlls with _stdcall; why doesnt com alt allow it?
it says that its not allowed to pass function pointers in the syntax of : void (*f)()
is there a different syntax, or is there a way to force this?
i really want to get/pass function pointers to vb...
i can do it using normal dlls with _stdcall; why doesnt com alt allow it?
quote:
i really want to get/pass function pointers to vb...
i can do it using normal dlls with _stdcall; why doesnt com alt allow it?
Playing with fire are we?
In order to do this, you need to take the "gentleman''s agreement" appraoch and cast those function pointers into long''s.
I don''t think VB will be able to use them, but this way it can at least store them. Then you can pass that long back into the COM object, and it can cast them back to function pointers.
***SAVE OFTEN***
Generally there''s another more OO approach than function-pointers which would be more VB friendly. What are you trying to accomplish?
...
quote:
Dim pComVirgin As Object
Set pComVirgin = CreateObject("ATLTutLib.ComVirgin")
MsgBox pComVirgin.Deflower
Acutally that won''t work with my example, we stripped out the IDispatch interface when we chose "custom" instead of "dual" in step 2. If you go back and pick dual, ATL will handle the IDispatch for you. VB no longer requires this (not even VBA!), and it''s about an order (or two) magnitudes faster not to use IDispatch. However, you can even use your object on web pages, with VBScript or JScript if you include IDispatch/dual support.
And if you think this COM stuff is pretty cool - .NET will let you declare a class in one language, and _inherit from it in another!
i am trying to create a dll for VB games, which creates and sustains an environment (dx), calling event/user functions written in vb.
this is why i need a c++ dll, to allow me to add callbacks to vb.
i realize this seems kind of dumb, but i know alot of non-c++''ers that could benifit.
how would i cast that pointer?
//
void (*always)();
myfunc(long addr)
{
always = (void (*)()) addr; // its not like this is it?
}
//
this is why i need a c++ dll, to allow me to add callbacks to vb.
i realize this seems kind of dumb, but i know alot of non-c++''ers that could benifit.
how would i cast that pointer?
//
void (*always)();
myfunc(long addr)
{
always = (void (*)()) addr; // its not like this is it?
}
//
If that''s what you want to do, then you should finish the DirectX team''s job and implement a connection point for the call backs. VB provides native support for connect point interfaces - "with events".
All of this would be easier to do with the ATL, if the Dx team provided .idl or .old files for thier interfaces. They only provide them for DirectShow, and those are missing the RPC qualifiers (sizeof, lengthis, etc...), better than nothing I guess
So you may need to reconstruct the .idl files for the DirectX objects. If you have a particular interface in mind, I''ll get you started if you''re willing to send me a copy of the finished .idl file
All of this would be easier to do with the ATL, if the Dx team provided .idl or .old files for thier interfaces. They only provide them for DirectShow, and those are missing the RPC qualifiers (sizeof, lengthis, etc...), better than nothing I guess
So you may need to reconstruct the .idl files for the DirectX objects. If you have a particular interface in mind, I''ll get you started if you''re willing to send me a copy of the finished .idl file
Actually, you _need to create a connection point object, because you''re going to need to marshal the call-backs to-and-from the STA (single thread apartment) of VB into the MTA (multi-threaded apartment, neutral apartment) of, say, DirectPlay.
To do this effectively, you almost need to implement a game engine in C++ that expose a COMpliant set of interfaces for VB to use.
To do this effectively, you almost need to implement a game engine in C++ that expose a COMpliant set of interfaces for VB to use.
You know, all this may be a mote point with .Net and Dx9
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement