3

I just created a DLL for my boss in MSVC++2010. I selected "New Win32 DLL" with option "Export symbols", so, everything is completely standard. There are some predefined exports in the new project files, a class, its constructor, a global function and variable with bogus values and a file dllmain.cpp with an APIENTRY function. I changed nothing yet.

Now my boss wants to use the exported things in his VB6 project. He started a VB6 project, did menu "Project" - "Links" (translated from German to English, so it might be somewhat different but I'm sure you know what I mean) and selected a DLL file, just as he says he usually does.

However, VB6 fails to include it, instead showing an error message "could not include DLL file" (no real reason given). The same occurred with a standard new DLL project from Visual C++ 6. My boss thinks it might be because the symbols are not really exported or VB6 needs some special declarations. Does anyone know what the problem is?

Felix Dombek
  • 13,664
  • 17
  • 79
  • 131

5 Answers5

7

Yeah, VB6 doesn't work like that. You need to declare the DLL functions in your VB code somewhat like this:

Private Declare Function WinHelp Lib "user32" Alias "WinHelpA" _
  (ByVal hwnd As Long, ByVal lpHelpFile As String, _
  ByVal wCommand As Long, ByVal dwData As Long) As Long

You would replace "user32" with "MyCPlusPlusDLL.dll" and use the actual method names and signatures etc. from your DLL. Then put the DLL in your /System folder and you should be good to go.

Note: this is assuming that the methods inside your C++ DLL are declared with "__declspec".

MusiGenesis
  • 74,184
  • 40
  • 190
  • 334
  • Thank you. Yes, I use `__declspec(dllexport)`. I assume I can't use a class then? – Felix Dombek Jan 28 '11 at 16:14
  • No classes allowed for non COM dll's. – Kris Erickson Jan 28 '11 at 16:19
  • @Felix: you can use classes internally (i.e. inside the DLL code) but you can't pass them in as parameters from VB6 or return them from external DLL functions. (I *think* this is true, anyway - not 100% sure, as I've never done it myself). – MusiGenesis Jan 28 '11 at 16:23
  • 4
    +1 I also strongly recommend reading Microsoft's manual [Developing DLLs for use with VB](http://vb.mvps.org/tips/vb5dll.asp). The document was written for VC++ 4.2 with VB5 and never updated, but it will still be very useful for VC++ 10 with VB6. Certainly nothing changed from VB5 to VB6 – MarkJ Jan 28 '11 at 17:02
  • Can I use global variables to maintain state between two function calls? Is APIENTRY function in my code called automatically when the DLL is loaded like this? And most importantly: is there a document online which answers all these questions? – Felix Dombek Jan 28 '11 at 18:14
  • 1
    @Felix: yes, you can use globals to maintain state inside the DLL. I don't know whether your APIENTRY function is called automatically; I don't think so, but that should be pretty easy to determine. The document `MarkJ` ref'ed seems to cover most of it. – MusiGenesis Jan 28 '11 at 18:27
  • @Felix: as a bit of advice, your life will be the happiest if you avoid trying pass any sort of strings back and forth. Stick to numerical types, and remember that `long` in Visual Basic is `int` in C/C++ (and VB's `int` is equivalent to `short` in C). – MusiGenesis Jan 28 '11 at 18:29
  • @MusiGenesis: thanks again, I'm currently reading the document ... but too bad -- I need to be passed a filename and give back a number :( hm ... maybe we could circumvent this by having the file in a predefined location like `temp` and call it `1.txt`, `2.txt` and so forth ... but what's the benefit? I only need the string in my function that gets it passed -- will it still be a problem? – Felix Dombek Jan 28 '11 at 18:37
  • @Felix: no, if I were you I'd go ahead and figure out how to pass in a string. I think Mark's linked article shows how to do it. Strings in the C world are just such a pain in the petard. – MusiGenesis Jan 28 '11 at 18:38
  • @MusiGenesis: I have found out that the `__declspec(dllexport)` is actually not correct for VB. You need a .DEF file instead. – Felix Dombek Oct 01 '11 at 16:03
2

I see you already accepted an answer, but this may be of use to you or others. The Universal DLL Function caller, by Paul Caton uses assembly language voodoo to enable VB6 to call different types of DLL functions not normally callable from VB6.

Joe Jordan
  • 2,372
  • 2
  • 17
  • 20
1

The easiest way to make a DLL in C++ and consume it from VB6 is to use COM.

Steve
  • 1,760
  • 10
  • 18
  • Any hints, maybe? I'm not new to C++ as a language but totally new to doing anything else than (no matter how elaborate) console programs with it. – Felix Dombek Jan 28 '11 at 15:41
  • 2
    I'm not sure "use COM" and "easiest way" should ever be in the same sentence. :) – MusiGenesis Jan 28 '11 at 15:46
  • @MusiGenesis It's *far* easier to write the VB6 client. Of course it's also *far* harder to write the C++ server :( – MarkJ Jan 28 '11 at 17:03
1

For a regular DLL, you can't use VB references, but rather need to use the Declare statement. Another option would to be create the DLL as an ActiveX component instead.

Kyle Alons
  • 6,955
  • 2
  • 33
  • 28
1

If it's not a COM library, you need to export only C function with __stdcall. You might need to create .def file for them (http://msdn.microsoft.com/en-us/library/d91k01sh(VS.80).aspx). Also use dependency walker, e.g. depends.exe to see what functions were exported and with which names.

Gene Bushuyev
  • 5,512
  • 20
  • 19