如何将 SWIG 生成的 C++ DLL 引用添加到 C# 项目?

dav*_*one 5 c# c++ swig

我正在使用 SWIG 生成一个 DLL,它将向 C# 项目公开 C++ 功能。此刻我:

  1. 定义 SWIG 接口文件

    %module example
    %{
    /* Includes the header in the wrapper code */
    #include "../pointmatcher/PointMatcher.h"
    %}
    
    ...
    
    %include "../pointmatcher/PointMatcher.h"
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用 SWIG 生成 .cxx 包装器

    swig.exe -c++ -csharp -outdir csharp example.i
    
    Run Code Online (Sandbox Code Playgroud)
  3. 通过 CMake 使用 MSBUILD 编译 .cxx 包装器

    # create wrapper DLL
    add_library(example SHARED ${WRAP_CSHARP_FILE})
    target_link_libraries(example pointmatcher)
    install(TARGETS example
            ARCHIVE DESTINATION ${INSTALL_LIB_DIR}
            LIBRARY DESTINATION ${INSTALL_LIB_DIR}
            RUNTIME DESTINATION ${INSTALL_BIN_DIR})
    
    Run Code Online (Sandbox Code Playgroud)

然后我有一个 DLL 文件 ( example.dll),我可以通过 Dependency Walker 检查该文件,并确认方法正在公开,如下所示:

DLL 的 Dependency Walker 检查

但是,当我尝试添加此 MSVC DLL 作为对 C# 项目的引用时,我收到错误“它不是有效的程序集或 COM 组件”。

基于如何在我的 C# Visual Studio 项目中添加 VC++ DLL 作为参考?我已经确认 SWIG 本身生成 P/Invoke 调用,并且tlbimp也无法识别 DLL。

Tim*_*m B 3

您不必像添加 C# dll 那样将 C++ dll 添加到项目中。相反,它是通过PInvoke系统调用的。

SWIG 将为您生成一些 C# 代码,访问 dll 的最简单方法是将这些文件包含在您的项目中,这些文件通过您可以调用的一些 C# 函数公开 dll 功能。

您也可以自己通过 PInvoke 使用该 dll。您需要创建一个充当包装器的 C# 函数:

C++ 头文件:

#ifndef TESTLIB_H
#define TESTLIB_H

extern "C" {
    int myfunc(int a);
}

#endif
Run Code Online (Sandbox Code Playgroud)

C++代码:

int myfunc(int a)
{
    return a+1;
}
Run Code Online (Sandbox Code Playgroud)

C# 代码:

using System;
using System.Runtime.InteropServices;

class Libtest
{
    [DllImport ("function")]
    private static extern int myfunc(int a);

    public static void Main()
    {
        int val = 1;
        Console.WriteLine(myfunc(val));
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

2
Run Code Online (Sandbox Code Playgroud)

DLL 的位置

编译后的 C++ dll 需要复制到 C# 项目 bin 目录中,或者如果路径已知,则可以将其添加到调用中DllImport

[DllImport("path/to/dll/function.dll")]
Run Code Online (Sandbox Code Playgroud)

要通过 swig 实现此目的,请使用以下-dllimport标志:

swig -cpp -csharp ... -dllimport "/path/to/dll/function.dll" ...
Run Code Online (Sandbox Code Playgroud)

如果您想动态设置路径(以允许加载在运行时动态选择的 32 位或 64 位版本),您可以使用 kernel32 函数,该函数SetDllDirectory也使用DllImport.