tags:

views:

2965

answers:

3

I've got a Windows DLL that I wrote, written in C/C++ (all exported functions are 'C'). The DLL works fine for me in VC++. I've given the DLL to another company who do all their development in VB. They seem to be having a problem linking to the functions. I haven't used VB in ten years and I don't even have it installed. What could be the problem?

I've declared all my public functions as follows:

define MYDCC_API __declspec(dllexport)

MYDCCL_API unsigned long MYDCC_GetVer( void); . . .

Any ideas?


Finally got back to this today and have it working. The answers put me on the right track but I found this most helpful:

http://www.codeproject.com/KB/DLL/XDllPt2.aspx

Also, I had a few problems passing strings to the DLL functions, I found this helpful:

http://www.flipcode.com/archives/Interfacing_Visual_Basic_And_C.shtml


+2  A: 

By using __declspec for export, the function name will get exported mangled, i.e. contain type information to help the C++ compiler resolve overloads.

VB6 cannot handle mangled names. As a workaround, you have to de-mangle the names. The easiest solution is to link the DLL file using an export definition file in VC++. The export definition file is very simple and just contains the name of the DLL and a list of exported functions:

LIBRARY mylibname
EXPORTS
    myfirstfunction
    secondfunction

Additionally, you have to specify the stdcall calling convention because that's the only calling convention VB6 can handle. There's a project using assembly injection to handle C calls but I guess you don't want to use this difficult and error-prone method.

Konrad Rudolph
+2  A: 

Try adding __stdcall at the end

#define MYDCC_API __declspec(dllexport) __stdcall

We have some C++ dlls that interact with our old VB6 apps and they all have that at the end.

Re0sless
A: 

A VB6 DLL is always a COM dll. I shall describe an example in as few words as possible. Suppose you have a ActiveX DLL project in VB6 with a class called CTest which contains a method as shown below

Public Function vbConcat(ByVal a As String, ByVal b As String) As String vbConcat = a & b End Function

and you have set the project name as VBTestLib in VB6 project properties and you have compiled the project as F:\proj\VB6\ActiveXDLL\VBTestDLL.dll

You need to register the dll using the Windows command regsvr32 F:\proj\VB6\ActiveXDLL\VBTestDLL.dll

now your C++ code :

#import "F:\proj\VB6\ActiveXDLL\VBTestDLL.dll" using namespace VBTestLib;

void CDialogTestDlg::OnButton1() {

 HRESULT hresult;
 CLSID clsid;
 _CTest *t; // a pointer to the CTest object
 _bstr_t bstrA = L"hello";
 _bstr_t bstrB = L" world"; 
 _bstr_t bstrR;
 ::CoInitialize(NULL);
  hresult=CLSIDFromProgID(OLESTR("VBTestLib.CTest"), &clsid);
  hresult= CoCreateInstance(clsid,NULL,CLSCTX_INPROC_SERVER,
                               __uuidof(_CTest),(LPVOID*) &t);
  if(hresult == S_OK)
  {
     bstrR  = t->vbConcat(bstrA , bstrB);
     AfxMessageBox((char*)bstrR);
   }

}

That's all there is to it, to get started off.

tracker