使用 SWIG 从 c# 使用 c++ uint8_t *
Use c++ uint8_t * from c# using SWIG
我有一个看起来像这样的功能:
virtual int64_t Read(uint8_t* buffer, int64_t bufferLength) = 0
我们想要覆盖(因为这是一个抽象 class)和来自 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 *)?
编译器的错误信息非常简单。您应该明确地将 void *
转换为 unsigned char *
.
尝试:
jresult = (long long) swig_callbackRead__SWIG_0(static_cast<unsigned char *>(jbuffer), jbufferLength);
这里的 directorin 类型映射似乎不太正确。我认为这应该足以修复它,在 %apply
指令之后的行上:
%typemap(directorin) uint8_t *buffer "$input = ;"
上述类型映射仅匹配名为 buffer
的非常量 uint8_t*
参数。如果我们愿意,我们可以使它更通用,例如:
%typemap(directorin) SWIGTYPE * "$input = ;"
将匹配任何没有更好匹配的内容,无论是常量还是非常量。我无法弄清楚为什么这不是默认设置,所以这里有一个风险,它可能会破坏我没有想到的其他地方,所以你可能更愿意继续在应用它的地方有选择性..
您也可以这样做:
%typemap(directorin) SWIGTYPE * "$input = (_ltype);"
或添加另一个变体:
%typemap(directorin) const SWIGTYPE * "$input = const_cast<_ltype>();"
我有一个看起来像这样的功能:
virtual int64_t Read(uint8_t* buffer, int64_t bufferLength) = 0
我们想要覆盖(因为这是一个抽象 class)和来自 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 *)?
编译器的错误信息非常简单。您应该明确地将 void *
转换为 unsigned char *
.
尝试:
jresult = (long long) swig_callbackRead__SWIG_0(static_cast<unsigned char *>(jbuffer), jbufferLength);
这里的 directorin 类型映射似乎不太正确。我认为这应该足以修复它,在 %apply
指令之后的行上:
%typemap(directorin) uint8_t *buffer "$input = ;"
上述类型映射仅匹配名为 buffer
的非常量 uint8_t*
参数。如果我们愿意,我们可以使它更通用,例如:
%typemap(directorin) SWIGTYPE * "$input = ;"
将匹配任何没有更好匹配的内容,无论是常量还是非常量。我无法弄清楚为什么这不是默认设置,所以这里有一个风险,它可能会破坏我没有想到的其他地方,所以你可能更愿意继续在应用它的地方有选择性..
您也可以这样做:
%typemap(directorin) SWIGTYPE * "$input = (_ltype);"
或添加另一个变体:
%typemap(directorin) const SWIGTYPE * "$input = const_cast<_ltype>();"