首页 文章

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

提问于
浏览
2

我正在使用SWIG生成一个DLL,它将C函数暴露给C#项目 . 目前我:

  • 定义SWIG接口文件
%module example
%{
/* Includes the header in the wrapper code */
#include "../pointmatcher/PointMatcher.h"
%}

...

%include "../pointmatcher/PointMatcher.h"
  • 使用SWIG生成.cxx包装器
swig.exe -c++ -csharp -outdir csharp example.i
  • 通过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})

然后我有一个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 回答

  • 1

    您不会像使用C#dll一样将C dll添加到项目中 . 而是通过PInvoke系统调用它 .

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

    您也可以自己通过PInvoke使用dll . 您需要创建一个C#函数作为包装器:

    C Headers :

    #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位版本),可以使用也使用 DllImport 加载的kernel32函数 SetDllDirectory .

相关问题