如何从 C++ 调用 VB.NET DLL(也调用函数 - 不仅仅是 DLL 文件)
Posted
技术标签:
【中文标题】如何从 C++ 调用 VB.NET DLL(也调用函数 - 不仅仅是 DLL 文件)【英文标题】:How to call VB.NET DLL from C++ (Call the functions also - not DLL file only) 【发布时间】:2011-05-13 12:19:41 【问题描述】:我想问一下如何从C++程序调用VB.NET DLL
我曾多次尝试从 C++ 调用 VB.NET DLL 文件,它工作正常,但问题是我无法调用 VB.NET DLL 文件的功能(我只能加载 VB.NET DLL 文件)
在 VB.NET DLL 中我有以下代码:
Public Function example_function1(ByVal i As Integer) As Integer
Return 3
End Function
Public Function example_function2(ByVal i As Integer) As Integer
Return 3
End Function
=============================
我的 C++ 代码是:
typedef int (__stdcall *ptf_test_func_1_type)(int);
typedef int (__stdcall *ptf_test_func_2_type)(int*);
int i =1;
HINSTANCE dll_instance = LoadLibrary("DLLs7.dll");
int main()
if(dll_instance !=NULL)
printf("The DLLs file has been Loaded \n");
cout << GetLastError() << endl;
ptf_test_func_1_type p_func1=(ptf_test_func_1_type)GetProcAddress(dll_instance,"Class1::example_function1");
ptf_test_func_2_type p_func2=(ptf_test_func_2_type)GetProcAddress(dll_instance,"Class1::example_function2");
// Function No 1 //
if (p_func1 != NULL)
cout << "\nThe function number 1 is " << p_func1(i) << endl;
else
cout << "\nFailed" << endl;
cout << GetLastError() << endl;
// Function No 2 //
if (p_func2 != NULL)
cout << "\nThe function number 2 is" << p_func2(&i) << endl;
else
cout << "\nFailed" << endl;
cout << GetLastError() << endl;
else
printf("\nDLLs file Load Error");
cout << GetLastError() << endl;
cout << GetLastError() << endl;
return(0);
我的以下步骤是:
1) 我已经创建了 VB.NET DLL。
2)我创建了一个新的应用程序visual C++并选择了“win32控制台应用程序”
3) 我已经编写了调用 DLL 和函数的代码(如您在上面看到的)
我是否因为可以调用 VB.NET DLL 文件但无法调用 VB.NET DLL 函数而遗漏了步骤或代码中的任何内容
如您所见,我已经编写了 GETLASTERRIR() 来查找错误
cout
但是我在失败时在函数中发现了这个错误 127,在调用 DLL 文件中发现了 203
谁能帮帮我
非常感谢
问候
【问题讨论】:
错误 127 表示“找不到指定的过程”。 VB.NET 无法导出这样的函数。您将需要使用 COM(使用由于您的 vb 程序集需要与“本机”可执行文件完全不同的运行时,因此您需要在两者之间使用一些层。这一层可能是COM。
您可以通过它的“ComVisible”属性将您的程序集公开给 COM 子系统。然后,您应该注册该程序集以将其公开给 COM“订阅者”。
只有这样你才能从你的 c++ 代码中#import
程序集命名空间。
注意:这是一篇非常简短版本的 msdn 文章“How to call a managed DLL from native Visual C++ code”
EDIT-- 刚刚试了一下...它似乎工作正常:
C#代码
namespace Adder
public interface IAdder
double add(double a1, double a2);
public class Adder : IAdder
public Adder()
public double add(double a1, double a2) return a1 + a2;
项目设置
[assembly: ComVisible(true)]
[assembly: AssemblyDelaySign(false)]
(需要签名才能生成 tlb)
C++ 代码:
#import <adder.tlb> raw_interfaces_only
CoInitialize(NULL);
Adder::IAdderPtr a;
a.CreateInstance( __uuidof( Adder::Adder ) );
double d = 0;
a->add(1.,1., &d);
// note: the method will return a HRESULT;
// the output is stored in a reference variable.
CoUninitialize();
【讨论】:
感谢您的重播。简而言之,我应该有 tlb 文件吗?因为我只有 DLL 文件。 @Hadi Al-Zaabi:你真的应该阅读这篇文章。RegAsm
是用于从程序集中创建 .tlb 文件的工具。【参考方案2】:
GetProcAddress 不理解 C++ 名称修改,更不用说任何其他修改,因此没有 "Class1::example_function1"
可以作为有效标识符的 dll。通常它只与extern "C"
(或在没有++ 的C 中实现)函数一起使用,这些函数不会被破坏。
如果它是在 VB.NET 中实现的,它根本就不是一个 dll。它是一个 .net 程序集,您需要在 CLR(.net 运行时)中运行才能使用它。您可以在 CLR 中运行 C++ 代码,但它必须是“托管 C++”,它使用特殊类型进行扩展,用于 .net 对象引用和垃圾收集器操作。
【讨论】:
你引用了与主题相关的事实,虽然你所说的一切都是真实的,但它并不能回答问题。 非常感谢您的重播。我已经尝试过 CLR 应用程序和 vb.net DLL 的加载,现在它可以正常工作,这意味着没有错误,但在调用函数时也存在问题。同样的问题 GeLAst 错误是 127。我如何在我的 C++ 代码中使用 extern "C"?问候【参考方案3】:您不能直接从本机 C++ 访问 .NET 代码,您需要 C++/CLI。
如果您的程序需要原生 C++,则可以编写混合模式包装 DLL,为主程序提供原生 C++ 接口,并在实现中使用 C++/CLI 将调用转发到 .NET动态链接库。
【讨论】:
【参考方案4】:您需要为此在 C++/CLI 上编写一个包装器。您可能会发现以下链接很有帮助。 http://www.codeproject.com/KB/mcpp/cppcliintro01.aspx
【讨论】:
以上是关于如何从 C++ 调用 VB.NET DLL(也调用函数 - 不仅仅是 DLL 文件)的主要内容,如果未能解决你的问题,请参考以下文章
VB.net编写的dll,供vb6调用时dll中的函数不可见?