如何从 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(使用 属性)或用 C++/CLI 语言编写包装类。需要这种胶水来初始化 CLR,以便您的程序可以执行托管代码。 【参考方案1】:

由于您的 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 调用VBS文件?

python可以调用易语言dll吗

VB.net编写的dll,供vb6调用时dll中的函数不可见?

用C语言如何写DLL动态链接库?VB.net 又如何调用其生成的DLL库?急急急!!!!在线等!!

vb.net如何动态调用WebService接口啊

vb.net把dll放到程序的Resources资源里面,能直接调用Resources里面的dll吗?