使用SWIG从C#向C++传递int数组与List<string>参数的问题求助
std::list<std::string>和int数组参数映射问题 我来帮你搞定这个SWIG包装C++代码时的类型映射问题,你遇到的SWIGTYPE_p_std__listT_std__string_t和SWIGTYPE_p_double(这里大概率是函数参数类型或SWIG配置的小失误),都是因为没给SWIG明确的模板实例化和数组类型映射规则导致的,咱们一步步调整接口文件:
1. 修复std::list<std::string>的类型映射
你已经包含了std_list.i和std_string.i,但SWIG需要显式实例化std::list<std::string>模板,才能生成对应C#的可互操作类型。在你的接口文件里,添加这一行:
%include <std_list.i> %include <std_string.i> // 新增:实例化std::list<std::string>的模板,让SWIG生成对应的C#包装类 %template(StringList) std::list<std::string>;
添加后,SWIG会生成一个StringList类,你可以直接用C#的List<string>初始化它,或者手动遍历添加元素:
// C#调用示例 var csharpStringList = new List<string> { "hello", "swig", "csharp" }; var swigStringList = new StringList(csharpStringList); // 直接把swigStringList传给C++函数即可
如果想要更无缝的体验(让C#的List<string>直接作为参数传入C++函数),可以加一段自定义类型映射:
// 在%include <std_list.i>之后添加 %typemap(cstype) std::list<std::string>& "System.Collections.Generic.List<string>" %typemap(csin) std::list<std::string>& "$csinput" %typemap(imtype) std::list<std::string>& "global::SWIGTYPE_p_std__listT_std__string_t" %typemap(cscode) std::list<std::string>& { public static implicit operator global::SWIGTYPE_p_std__listT_std__string_t(System.Collections.Generic.List<string> list) { var swigList = new StringList(list); return swigList.CPtr; } }
这样就能直接把C#的List<string>传给C++的std::list<std::string>&参数,不用手动转StringList了。
2. 修复int数组的类型映射
你提到得到的是SWIGTYPE_p_double,首先要确认你的C++函数参数确实是int数组/指针(而不是double类型,这很可能是问题的源头)。确认后,调整arrays_csharp.i的使用:
%include <arrays_csharp.i> // 告诉SWIG把C#的int[]映射到C++的int指针(数组形式) %apply int INPUT[] { int* }; // 如果是输出数组(需要从C++返回数据到C#),用OUTPUT[] %apply int OUTPUT[] { int* };
如果你的C++函数用的是std::vector<int>而非原生数组,那需要换用std_vector.i并实例化模板:
%include <std_vector.i> %template(IntVector) std::vector<int>;
生成的IntVector类可以和C#的List<int>、int[]直接转换。
调整后的完整SWIG接口示例
把这些修改整合到你的接口文件里,最终大概是这样:
%module (directors="1") CppTestApp %{ #include "TestClass.h" #include "TestDataClass.h" %} %include <windows.i> %include <std_list.i> %include <std_string.i> // 实例化std::list<std::string>模板 %template(StringList) std::list<std::string>; %include <arrays_csharp.i> // 映射int数组参数 %apply int INPUT[] { int* }; %feature("director") Base; %include "TestClass.h" %include "TestDataClass.h"
额外小提醒
- 如果C++函数参数是
const std::list<std::string>&,记得把类型映射里的std::list<std::string>&也改成带const的版本 - 编译前记得清理之前生成的SWIG代码和编译产物,避免旧代码干扰
内容的提问来源于stack exchange,提问作者Hari Sankar v m

