我正在使用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检查它,并确认方法如下所示:
但是,当我尝试将此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。
答案 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
编译好的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
。