我正在使用SWIG生成对本机32位c++ dll的包装。 SWIG生成一个C++包装文件和许多生成的C#代码,将其编译成一个dll(C++ / CLI和C#项目均以x86形式构建),并且所得函数可以通过C#fine调用,但包含枚举的函数除外。一个例子:
SWIG生成的interface_wrap.cxx文件:
SWIGEXPORT int SWIGSTDCALL CSharp_myMethod(long jarg1, long jarg2, void * jarg3, void * jarg4) {
int jresult ;
long arg1 ;
long arg2 ;
myEnum arg3 ;
double *arg4 = 0 ;
myEnum const *argp3 ;
int result;
arg1 = (long)jarg1;
arg2 = (long)jarg2;
argp3 = (myEnum *)jarg3;
if (!argp3) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null myEnum const", 0);
return 0;
}
arg3 = *argp3;
arg4 = (double *)jarg4;
if (!arg4) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "double & type is null", 0);
return 0;
}
result = (int)myMethod(arg1,arg2,arg3,*arg4);
jresult = result;
return jresult;
}
C#extern函数委托(delegate)定义:
[global::System.Runtime.InteropServices.DllImport("ProjectWrapper", EntryPoint="CSharp_myMethod")]
public static extern int myMethod(int jarg1, int jarg2, [MarshalAs(UnmanagedType.U4)]myEnum jarg3, out double jarg4);
Interface.i文件提取:
%module ProjectWrapper
%{
#include "myEnumDefinition.h"
%}
%include "enums.swg"
// %typemap(csbase) myEnum "short" // is something like this needed??
%typemap(cstype, out="myEnum") myEnum&, const myEnum& "ref myEnum"
%typemap(cstype, out="myEnum") myEnum, const myEnum "myEnum"
%typemap(imtype, inattributes="[MarshalAs(UnmanagedType.U4)]", outattributes="[return: MarshalAs(UnmanagedType.U4)]", out="myEnum") myEnum&, const myEnum& "ref myEnum"
%typemap(imtype, inattributes="[MarshalAs(UnmanagedType.U4)]", outattributes="[return: MarshalAs(UnmanagedType.U4)]") myEnum, const myEnum "myEnum"
%typemap(csin) myEnum&, const myEnum& "ref $csinput"
%typemap(csin) myEnum, const myEnum "$csinput"
int myMethod(const long start,const long end,const myEnum enumvalue, double& result);
枚举的C#定义:
public enum myEnum {
myEnum_value1,
myEnum_value2,
myEnum_value3
}
枚举的C++定义(来自myEnumDefinition.h)
enum myEnum
{
myEnum_value1,
myEnum_value2,
myEnum_value3
};
当到达调用C#myMethod extern委托(delegate)的地步时,它每次都会抛出AccessViolationException。如果我尝试调用没有任何枚举作为参数的其他方法,则可以正常工作。
我不明白这里出了什么问题。我试图以不同的方式对枚举进行
MarshalAs
编码,但我无法避免避免引发此异常。生成包装程序时,SWIG接口(interface)文件中是否缺少某些内容? 最佳答案
根据这一行,Swig似乎期望有一个指向枚举值的指针:
argp3 = (myEnum *)jarg3;
看起来C++方法在其第三个参数中期望
myEnum*
值。因此,您应该将您的enum参数作为引用传递:public static extern int myMethod(int jarg1, int jarg2, ref myEnum jarg3, out double jarg4);
关于c# - 为什么在SWIG/C#中包含c++方法的枚举会导致AccessViolationException?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29373894/