我正在使用 SWIG 生成一个 DLL,它将向 C# 项目公开 C++ 功能。此刻我:
定义 SWIG 接口文件
%module example
%{
/* Includes the header in the wrapper code */
#include "../pointmatcher/PointMatcher.h"
%}
...
%include "../pointmatcher/PointMatcher.h"
Run Code Online (Sandbox Code Playgroud)使用 SWIG 生成 .cxx 包装器
swig.exe -c++ -csharp -outdir csharp example.i
Run Code Online (Sandbox Code Playgroud)通过 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 检查该文件,并确认方法正在公开,如下所示:
但是,当我尝试添加此 MSVC DLL 作为对 C# 项目的引用时,我收到错误“它不是有效的程序集或 COM 组件”。
基于如何在我的 C# Visual Studio 项目中添加 VC++ DLL 作为参考?我已经确认 SWIG 本身生成 P/Invoke 调用,并且tlbimp也无法识别 DLL。
您不必像添加 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)
编译后的 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.
| 归档时间: |
|
| 查看次数: |
3870 次 |
| 最近记录: |