从 C 调用用 VB6 制作的 DLL

Posted

技术标签:

【中文标题】从 C 调用用 VB6 制作的 DLL【英文标题】:calling a DLL made in VB6 from C 【发布时间】:2009-05-15 01:17:59 【问题描述】:

好的,这个问题与我遇到的最后一个问题相反......我觉得我很接近得到它,但它只是不起作用。 之前,我试图用 C 编译一个 DLL,然后从 VB 调用它,但我意识到这并不是我真正想要的(我希望程序用 C 编写,同时使用 VB 前端,而不是前端是程序并使用 DLL 的功能)。

所以现在,我正在 VB 中编译一个 DLL 并尝试从 C .exe 中调用它。

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

这是我导出的虚拟函数:

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

我可以从另一个 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

并且,来自 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;

当我调试时,我发现我遇到了访问冲突,这在过去意味着我在 VB 函数中忘记了 ByVal,它正在传递对 5 或其他东西的引用。但是我在这里看不出有什么问题...我从 DLL 中获得了与我从 dumpbin 获得的偏移量相匹配的 ProcAddress,我可以从 VB 中调用它,但是 C 调用者遇到了访问冲突...

有什么想法吗?有人看到我忽略的东西吗?我意识到我正在做一些非常晦涩且几乎闻所未闻的事情,而不是仅仅学习如何用 C 设计前端,但现在我决心修复它。

【问题讨论】:

出于好奇,你能解释一下用VB6编写接口并调用C DLL有什么问题吗? VB6 界面可以是一个非常薄的包装器——“被动屏幕”如果你喜欢martinfowler.com/eaaDev/PassiveScreen.html 我可以,我可能也会在其他项目中使用它,但我认为知道如何这样做会很有用 【参考方案1】:

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

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

(无意冒犯,但你是在重新发明***,而不是开辟新天地!我也在 this answer 上链接到 vbAdvance。)

【讨论】:

【参考方案2】:

您必须在导出的函数中手动初始化 VB6 运行时,然后才能在运行时中使用任何函数。查看Compact In-Process Multi-threading 示例,ThreadEntry 函数显示了如何执行此操作。

【讨论】:

【参考方案3】:

您必须通过 COM 接口调用它,不是吗? Something more like this.

【讨论】:

天哪...“...void main(void)(用于控制台应用程序)”不是 voidmainvoid!

以上是关于从 C 调用用 VB6 制作的 DLL的主要内容,如果未能解决你的问题,请参考以下文章

从 VB6 调用 C dll,其中 dll 是使用 Visual Studio 2013 编写的

找不到从 VB6 调用的 C++ DLL 程序

如何从 C++/CLI 调用 VB6 COM

VB6可以调用C#COM对象重载方法[关闭]

从 C++ 调用 C#

VB6 使用 .Net dll。无法读取 app.config