c# - 使用 SWIG 从 c# 使用 c++ uint8_t *

标签 c# c++ swig

我有一个看起来像这样的函数:

virtual int64_t Read(uint8_t* buffer, int64_t bufferLength) = 0

我们想要覆盖(因为这是一个抽象类)并从 c# 代码(使用 director)实现。使用

%include "arrays_csharp.i"
%apply uint8_t INPUT[] {uint8_t* buffer}

我能够得到带有签名的c#翻译

public virtual long Read(byte[] buffer, long bufferLength)

这就是我想要的。但是在尝试编译 SWIG 代码时,我们收到如下错误:

 error C2440: '=': cannot convert from 'void *' to 'unsigned char *'
 note: Conversion from 'void*' to pointer to non-'void' requires an explicit cast

因为生成的 swig cc 文件中有这个 lins:

 int64_t c_result = SwigValueInit< int64_t >() ;
 long long jresult = 0 ;
 unsigned char* jbuffer = 0 ;
 long long jbufferLength  ;
 long long jbufferOffset  ;

 if (!swig_callbackRead__SWIG_0) {
    throw Swig::DirectorPureVirtualException("mip::Stream::Read");
  } else {
    jbuffer = (void *) buffer; <========= FAIL LINE
    jbufferLength = bufferLength;
    jresult = (long long) swig_callbackRead__SWIG_0(jbuffer, jbufferLength);
    c_result = (int64_t)jresult; 
  }

我如何告诉 SWIG 不要强制转换为 (void *)?

最佳答案

看起来 directorin 类型映射在这里不太正确。我认为这应该足以修复它,在 %apply 指令之后的行中:

%typemap(directorin) uint8_t *buffer "$input = $1;"

上述类型映射仅匹配名为 buffer 的非常量 uint8_t* 参数。如果我们愿意,我们可以使它更通用,例如:

%typemap(directorin) SWIGTYPE * "$input = $1;"

将匹配任何没有更好匹配的内容,const 或非常量类似。我无法弄清楚为什么这不是默认的,所以这里有一个风险,它可能会破坏我没有想到的其他地方,所以你可能更愿意继续在应用它的地方有选择性..

你也可以这样做:

%typemap(directorin) SWIGTYPE * "$input = ($1_ltype)$1;"

或者添加另一个变体:

%typemap(directorin) const SWIGTYPE * "$input = const_cast<$1_ltype>($1);"

关于c# - 使用 SWIG 从 c# 使用 c++ uint8_t *,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50677162/

相关文章:

c# - System.Runtime.Serialization.Json.DataContractJsonSerializer.WriteObject 在序列化时忽略 NonSerialized 属性

c# - 为什么 null 合并运算符会破坏我在 c# 中的字符串赋值?

c++ - 向 C++ 文件添加命名空间的脚本

c# - AspNetCore 集成测试多个 WebApplicationFactory 实例?

c# - 将字节从文本框转换为字节数组再转换为字符时的奇怪行为?

c++ - C++程序中的基本指针问题

c++ - 局部变量作为非类型模板参数

c++ - 仅在特定翻译单元中找不到头文件

python - Swig -outdir 选项不包含 .so 文件

python - 如何使用 SWIG 从 C++ 无序映射生成 Python 字典?