从C调用VB6中生成的DLL

时间:2020-12-18 16:34:23

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).

好吧,这个与我最后一个挣扎的问题相反......我觉得我太接近了,但它只是不起作用。之前,我试图在C中编译DLL,然后从VB调用它,但我意识到这不是我想要的(我希望程序用C语言编写,而使用VB前端,而不是前端是程序和使用DLL的功能)。

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

所以现在,我正在编译VB中的DLL并尝试从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.

“但是等等,你不能用VB编译DLL!”实际上,我拦截了VB6.EXE对链接器的调用,并为我希望它导出的函数添加了一个定义文件,这里是最好的部分 - 如果我将dll复制到system32,我可以从另一个VB程序调用这些函数它工作正常。唯一的问题是,我似乎无法从C加载它。好吧,我可以,我得到了句柄,我得到了函数的地址,它只是程序失败了。

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:

我可以从另一个VB6程序中调用它:

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:

而且,来自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...

当我调试时,我发现我遇到了一个访问冲突,过去这意味着我在VB函数中忘记了ByVal,并且它将引用传递给5或者其他东西。但是我在这里看不到任何错误...我从DLL中获取了与来自dumpbin的偏移相匹配的ProcAddress,我可以从VB调用它,但是C调用者正在获取访问冲突...

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.

有任何想法吗?有人看到我忽略的东西吗?我意识到我正在做一些非常模糊和大多数闻所未闻的事情,而不仅仅是学习如何在C中设计前端,但现在我决定修复它。

3 个解决方案

#1


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

只需使用免费的外接程序vbAdvance。它允许您创建可从C(而不是COM DLL)调用的标准DLL。

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.

它还使您可以访问许多其他高级构建功能和许多IDE便利功能。创建控制台应用程序,在DLL中创建DllMain入口点,为XP样式创建XP Manifest编译器,支持终端服务器等。

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

(没有冒犯,但你在这里重新发明*,没有突破新的领域!我也在这个答案上与vbAdvance联系。)

#2


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.

在运行时使用任何函数之前,必须在导出的函数中手动初始化VB6运行时。查看Compact In-Process多线程示例,ThreadEntry函数显示了如何执行此操作。

#3


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

你必须通过COM接口调用它,不是吗?更像这样的东西。

#1


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

只需使用免费的外接程序vbAdvance。它允许您创建可从C(而不是COM DLL)调用的标准DLL。

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.

它还使您可以访问许多其他高级构建功能和许多IDE便利功能。创建控制台应用程序,在DLL中创建DllMain入口点,为XP样式创建XP Manifest编译器,支持终端服务器等。

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

(没有冒犯,但你在这里重新发明*,没有突破新的领域!我也在这个答案上与vbAdvance联系。)

#2


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.

在运行时使用任何函数之前,必须在导出的函数中手动初始化VB6运行时。查看Compact In-Process多线程示例,ThreadEntry函数显示了如何执行此操作。

#3


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

你必须通过COM接口调用它,不是吗?更像这样的东西。