使用 SWIG 和 C# 时将 char* 缓冲区转换为字节数组

mra*_*190 5 c# arrays buffer swig char

我维护一个 C++ SDK,现在需要转换为其他语言(特别是 C# 和 Java)。我正在使用 SWIG 生成包装器代码并成功完成 Java 工作。我现在需要让 C# 工作。

我有一个 C++ 函数(忽略Header函数签名中的对象 - 我已经解决了)

int send(Header header, char *payload);
Run Code Online (Sandbox Code Playgroud)

此外,我有一个directorC++ 类,如下所示:

class Callbacks {
public:
    virtual ~Callbacks() { }
    virtual void receive(Header header, char *payload) { }
};
Run Code Online (Sandbox Code Playgroud)

这允许我在 Java 和 C# 代码中创建回调。

我需要C# 中的send以下函数签名:receive

int send(Header header, byte[] payload);
Run Code Online (Sandbox Code Playgroud)

void receive(Header header, byte[] payload);
Run Code Online (Sandbox Code Playgroud)

SWIG 中的类型映射似乎是可行的方法,因此这是我对 C# 类型映射的尝试:

%module(directors="1") example

%{
#include "example.h"
%}

%feature("director") Callbacks;

%include "arrays_csharp.i"
CSHARP_ARRAYS(char, byte)
%typemap(imtype, inattributes="[In, MarshalAs(UnmanagedType.LPArray, SizeConst=2048, ArraySubType=UnmanagedType.U1)]") char INPUT[] "byte[]"

%apply char INPUT[] {char *payload}

%include "example/include/example.h"
Run Code Online (Sandbox Code Playgroud)

该接口文件的结果得到了我想要的函数签名,但我的字节数组只有大小 1,而且我只得到了原始字符缓冲区中的第一项。似乎 SWIG 将 char* 解释为指向 char 的指针,因此将 char* 缓冲区中的第一个元素粘贴到字节数组中并称其为良好。但我想创建一个大小为 2048 的字节数组(有效负载的大小不会大于该大小)并从 char* 缓冲区填充该字节数组。如果有什么区别的话,我的Header类对象具有 char* 缓冲区的大小,但我现在真的可以不关心它,而坚持使用 2048 字节的整体大小。

想法或帮助将不胜感激!

@Flexo 我在 StackOverflow 上看过你的其他 SWIG 帖子,你似乎是我的人帮助我的。手指交叉你看到这个!

Mat*_*t T 4

我也遇到了同样的问题,刚刚开始工作。

C++如下

// 访问.h

class Access
{
    void foo(unsigned char *inputBytes, int nbytes);
};
Run Code Online (Sandbox Code Playgroud)

Swig .i 文件如下。%apply 出现在要包装的代码的 %include之前似乎很重要。如果是在之后,那么什么都不会改变。

%include "arrays_csharp.i"
%apply unsigned char INPUT[]  {unsigned char *inputBytes}  
%include "Access.h"
Run Code Online (Sandbox Code Playgroud)

那么C#就是这样的

byte[] data = ...
var access = new Access();
access.foo(fileBytes, fileBytes.Length);
Run Code Online (Sandbox Code Playgroud)

使用 swig 3.0.2 我根本无法让它工作。使用 swig 3.0.12 我成功了。

我还不需要输出数组,但此方法至少可以与 C# 中的预分配缓冲区一起使用。