tags:

views:

78

answers:

4
+1  A: 

A VB6 DLL is normally a COM server. You do in fact have the equivalent of a .h file, it has a type library embedded in it. Start this off with Project + Properties, Common Properties, Framework and References. Add New Reference button, Browse tab, select the DLL.

Next, View + Object Browser. You should see the generated Interop library in the list. Open the node to see what is there. You write normal managed code, like gcnew, to create the COM object and call the interface methods. You do need some minimum documentation on the available methods to have a guess at how they should be called.

Hans Passant
You are right, when I do this I can see the list of functions in the DLL in the Object Browser. It shows Get_Data(System::String).
John
Whooptidoo. Please close your thread by marking the answer.
Hans Passant
I'm still struggling with the last portion of creating the COM object and calling the interface methods. I have not done that before.
John
I don't know what that means. Ask a real question, get a real answer. Is this really a "minimum documentation" problem?
Hans Passant
Sorry for being a pain. I'm still reading the COM article suggested by jdehaan but it is well beyond my experience. I see the functions in the Object Browser but I do not know what I need to do to call them in in my program. I tried simply calling Get_Data(Handle); but it was not recognized. I also tried to call CoInitialize first, but that did not help. For documentation, all I know is the form mentioned before "Public Function Get_Data(ByVal Handle As String) As String", which will return a string with a value between -16777216 and +16777215. What must I write now to call the function?
John
This should be a new question. I can't fit the answer in a comment box.
Hans Passant
Sure, I'll make one: http://stackoverflow.com/questions/3688325/calling-a-visual-basic-dll-in-c-part-2
John
A: 

It sounds like the DLL isn't actually exporting a function named Get_Data. Open up a command prompt and use dumpbin to get the list of exports of the DLL, e.g.:

dumpbin /exports "Sensor DLL.dll"

(dumpbin.exe is located in VC\bin within your Visual Studio install folder, which istypically something like C:\Program Files\Microsoft Visual Studio 10.0).

Then, replace Get_Data with the actual entry point and see if you have any better luck.

Adam Rosenfield
I tried this and dumpbin /exports returned the following: "File Type: DLL, Summary 2000 .reloc 2000.rsrc 2000.sdata C000.txt" - That was all
John
A: 

A Visual basic program normally needs a runtime to execute.

If you have a COM object (implemented in VB) use the COM API to communicate with it from C++. You will have to register the COM first. Here is a thread that explains hot to do that: http://forums.devx.com/archive/index.php/t-87059.html

If you use a .NET language, use the method of Hans Passant with a reference that will create an interop dll for you. This is far much easier.

  • Method 1: Do not do that, if you have a COM object that you want to use from a .NET environment, reference it.
  • Method 2: You get errors because you lack the the .lib file to properly link to the DLL (statically dynamically linking)
  • Method 3: Would be a pure dynamic solution but you have to know the exact names of the methods in the DLL. These may vary according to the parameters and calling convention used. This is very similar (actually identical, I would say) to the issue you face with your Method 1 solution. The name of the method is for yure not "Get_Data" but something else. With a tool like the dependency viewer you can have a look at the exported names.

Even Method 3 with the right names is likely to fail because if it is a COM object you will need some environment called Appartment to use the COM objects. You "enter" this appartment by calling CoInitialize. This creates some magical stuff in the TLS (Thread Local Storage) to perform the COM magic. I hope this explains why your tries will be pointless if the DLL you have is happening to be a COM component, what is quite likely according to the ATL like naming we can see.

EDIT: I forgot to say that you can also easily see what is inside the dll if it is a COM with the OLE/COM Viewer (normally if you have a compiler you will have such a tool around).

jdehaan
I am unfamiliar with COM objects but will do some reading. Thanks for the link. However, I am unable to open the DLL with the OLE/COM Viewer, which gives the error: IMoniker::BindToObject failed on the file moniker created from (....). Bad extension for file. MK_E_INVALIDEXTENSION($800401E6). Perhaps it is not a COM?
John
+1  A: 

I believe the missing piece is the calling convention. C++ has its own function calling convention different than VB6 (I assume VB6 since you haven't stated VB.NET explicitly). VB6 uses STDCALL convention whereas C++, depending on the vendor, uses a different calling convention termed __cdecl, which is why you see the __cdecl in the compiler error line for method #2. It assumes your external function is using that calling convention by default. Calling convention is a set of rules describing how functions call one another; specifically about how registers are used, what order parameters are delivered in, how by-value / by-reference is determined, etc.

I would suggest sticking with method #3 since method #1 is for Managed C++ which is not standard C++, and method #2 is unfamiliar to me and looks a bit ambiguous. What you want to try is declaring the function pointer typedef to use STDCALL.

typedef BSTR (__stdcall *Get_Data_Ptr)(BSTR Handle);
James Dunne
Thanks, I gave this a try but got the same error
John