tags:

views:

680

answers:

3

Okay, this one is the reverse of the last question I struggled with... I feel like I'm sooo close to getting it but it's just not working. Before, I was trying to compile a DLL in C, and then call it from VB, but I realized that's not really what I want (I want the program to be written in C, while using a VB frontend, not the frontend being the program and using the functionality of a DLL).

So now, I'm compiling a DLL in VB and trying to call it from a C .exe.

"But wait, you can't compile a DLL with VB!" Actually, I intercepted VB6.EXE's call to the linker, and added a definition file for the functions I want it to export, and here's the best part--if I copy the dll to system32, I can call the functions from another VB program and it works fine. Only thing is, I can't seem to load it from C. Well, I can, and I get the handle, and I get the address of the functions, it's just the program fails.

Here's the dummy function I exported:

Public Function PopupMessage(ByVal rawr As Integer) As Integer
    Msgbox "HERE BE " & rawr & " DRAGON(S)."
    PopupMessage = 4
End Function

I can call it like this from another VB6 program:

Public Declare Function PopupMessage Lib "vbdll" _
    (ByVal howmanydragons As Integer) As Integer

Private Sub Command1_Click()
    If IsNumeric(Text1.Text) Then
        Text2.Text = PopupMessage(Text1.Text)
    End If 
End Sub

and, from C:

int main(){
  typedef short int (*vbfun)(short int); //VB6 "Integer" is 16 bits
  vbfun popup_message;
  HANDLE dllhnd;
  dllhnd = LoadLibrary("vbdll.dll");
  if(dllhnd>(void*)HINSTANCE_ERROR){
    popup_message = (vbfun)GetProcAddress(dllhnd, "PopupMessage");
    printf("%d", popup_message(3));
  }
  return 0;
}

when I debug, I find out that I'm getting an access violation which, in the past has meant that I forgot ByVal in the VB function, and it was passing a reference to 5 or something. But I can't see anything wrong here... I get the ProcAddress from the DLL which matches the offset I get from dumpbin, I can call it from VB, but the C caller is getting an access violation...

Any ideas? Anyone see something that I've overlooked? I realize I'm doing something pretty obscure and mostly unheard of, instead of just learning how to design a front end in C, but now I'm determined to fix it.

A: 

You would have to call it through the COM interface, no? Something more like this.

JP Alioto
oh god..."...void main( void )(for the console applications)"not voidmainvoid!
Carson Myers
+2  A: 

Just use the free add-in vbAdvance. It lets you create standard DLLs that are callable from C (rather than COM DLLs).

It also gives you access to many other advanced build features and many IDE convenience features. Create console apps, create a DllMain entry point in your DLLs, XP Manifest compiler for XP styles, support Terminal Server, etc.

(No offence, but you are reinventing the wheel here, not breaking new ground! I linked to vbAdvance on this answer too.)

MarkJ
A: 

You have to initialize VB6 run-time manually in your exported function, prior to using any function in the run-time. Check out the Compact In-Process Multi-threading sample, the ThreadEntry function shows how to do it.

cheers,
</wqw>

wqw