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

时间:2015-08-04 10:48:49

标签: 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"
    
  2. 使用SWIG生成.cxx包装器

    swig.exe -c++ -csharp -outdir csharp example.i
    
  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})
    
  4. 然后我有一个DLL文件(example.dll),我可以通过Dependency Walker检查它,并确认方法如下所示:

    Dependency Walker inspection of DLL

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

    根据How can I add a VC++ DLL as a reference in my C# Visual Studio project?的答案,我已确认SWIG本身会生成P / Invoke调用,tlbimp也无法识别DLL。

1 个答案:

答案 0 :(得分:1)

您不会像使用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

C ++代码:

int myfunc(int a)
{
    return a+1;
}

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));
    }
}

输出:

2

DLL的位置

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

[DllImport("path/to/dll/function.dll")]

要使用swig实现此功能,请使用-dllimport标志:

swig -cpp -csharp ... -dllimport "/path/to/dll/function.dll" ...

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