【问题标题】:Calling functions inside a vb.net-comvisible dll from c++从 c++ 调用 vb.net-comvisible dll 中的函数
【发布时间】:2015-10-27 12:34:37
【问题描述】:

我在 vb.net (vs 2012) 中编写了一个 dll,其中的类和函数变得可见。像这样:

Imports System
Imports System.Runtime.InteropServices
Imports System.Windows.Forms

<ComClass(InterFc.ClassId, InterFc.InterfaceId, InterFc.EventsId)> _
Public Class InterFc

  Public Const ClassId As String = "553CCD79-3067-44DE-B1AD-36A153F5C965"
  Public Const InterfaceId As String = "8C15295C-477B-434F-9FDC-4626D418DA9E"
  Public Const EventsId As String = "C434DF40-3F7B-45EE-B0D8-C85ABED03E88"

'(...)'

  Public Function TestFkt(ByVal intValue As Integer) As Integer

    TestFkt = 5 * intValue

  End Function

  Public Sub New()
    MyBase.New()
  End Sub

'(...)

End Class

首先我想知道为什么 depency walker 中的函数列表是空的,但这不是问题。

从 VBScript 调用函数可以正常工作,如下所示:

Dim objCom
Dim iCounter

set objCom = CreateObject("VBNetDLL.InterFc")

For iCounter = 1 To 20
  MsgBox objCom.TestFkt(iCounter * 7)
Next

从 VisualBasic (VB6) 调用函数也可以正常工作:

Dim objCom

Set objCom = CreateObject("VBNetDLL.InterFc")

Msgbox objCom.TestFkt(3 * 7)

(好吧,代码看起来一样,但相信我,一个是 VBScript,另一个是 Visual Basic ;-))

我终生无法工作的是从 C++(VS 2012)调用这些相同的函数。我尝试了很多东西,都是从

开始的
#import <VBNetDLL.tlb>
using namespace VBNetDLL;

奇怪的是,Intellisense 将 VBNetDLL::InterFC 显示为“结构”,而不是一个类。 我尝试过的事情包括:

InterFc *objControl = new InterFc;

这给了我“没有合适的默认构造函数可用”和“不允许不完整的类型”,并且:

CoInitializeEx(0, COINIT_MULTITHREADED); 
CLSID clsid; 
HRESULT hr = CLSIDFromProgID(L"InterFc", &clsid);

InterFc *pWApp;
hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL,IID_IUnknown, (void **)&pWApp);

编译得很好,但尝试“pWApp->TestFkt”告诉我“使用未定义类型'VBNetDLL::InterFc'”,“'->TestFkt' 的左侧必须指向类/结构/联合/通用类型”和“不允许指向不完整类类型的指针”。

长话短说:我如何从 C++ 中调用这些成员函数,尤其是因为在 VBScript 和 VisualBasic6 中使用它们似乎很容易?

【问题讨论】:

  • 您的 VBA/VB6 示例代码使用后期绑定,您从不命名类的类型。值得注意的是,自动完成功能在 VB6 编辑器中不起作用。但是您尝试在 C++ 代码中使用早期绑定。 某人必须声明InterFc。有人需要成为#import directive。当心学习曲线,不要以为你可以尝试一下。您必须阅读文档才能正确处理。
  • 汉斯您好,感谢您的回答。好吧,我尝试的东西是我从这个论坛中学到的方法,但不幸的是没有成功。感谢您提到早期和晚期绑定,我会调查的。愿意为我指出一些有关阅读文档的方向吗? - 哦,对不起,我刚刚看到你的答案中有一个链接,也谢谢你。
  • 您好,抱歉,我还是不明白。我阅读了#import-doc,并查看了生成的 .tlh 和 .tli 文件,但没有看到任何向我展示的东西(强调“我”;-))我如何才能做到这一点。我是否必须更改原始 DLL 中的类定义? #import 有一些参数(虽然我没有看到)?

标签: c++ vb.net


【解决方案1】:

好的,对于那些可能偶然发现相同问题的人,这是我最终实现此功能的方法:

  CoInitialize(NULL); 

  _InterFcPtr pInterFC(__uuidof(InterFc));

  int iTestResult = (int)pInterFC->TestFkt(2);

直接告诉我而不是“阅读 F** 手册!”不是更容易吗。好吧,也许不是更容易,但更好,但聪明(比其他人)似乎比善良更重要。

还是谢谢。

【讨论】: