SWIG和PInvoke学习(1)
1. 简介
SWIG是个帮助使用C或者C++编写的软件能与其它各种高级编程语言进行嵌入联接的开发工具。
SWIG能应用于各种不同类型的语言包括常用脚本编译语言例如Perl, PHP, Python, Tcl, Ruby and PHP。支持语言列表中也包括非脚本编译语言,例如C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Modula-3, OCAML以及R,甚至是编译器或者汇编的计划应用(Guile, MzScheme, Chicken)。SWIG普遍应用于创建高级语言解析或汇编程序环境,用户接口,作为一种用来测试C/C++或进行原型设计的工具。SWIG还能够导出XML或Lisp s-expressions格式的解析树。
SWIG可以被*使用,发布,修改用于商业或非商业中。
2.使用方法学习
从官网下载了swigwin-2.0.11。
Swig使用大概有两种方式,一种是配置Vs对外部工具,一种是配置环境变量通过Cmd命令。前一种方法比较简单,Vs2010配置如图。
测试使用的步骤和相关的类。
1.新建VC Win32空项目Dll
2. 添加类CMath
1 #pragma once 2 class CMath 3 { 4 public: 5 CMath(void); 6 ~CMath(void); 7 int Add(int a, int b); 8 int n; 9 };
实现文件:
1 #include "Math.h" 2 3 4 CMath::CMath(void) 5 { 6 } 7 8 9 CMath::~CMath(void) 10 { 11 } 12 13 14 int CMath::Add(int a, int b) 15 { 16 return a+b; 17 }
3.添加一个test.i文件,添加代码,注意module名要和编译C++的dll名称一致。
当前页执行外部工具Swig,生成4个文件:Test_wrap.cxx,CMath.cs,MathLib.cs和MathLibPINVOKE.cs。
1 %module MathLib 2 %include <windows.i> 3 4 %{ 5 #include "Math.h" 6 %} 7 8 %include "Math.h"
1 /* ---------------------------------------------------------------------------- 2 * This file was automatically generated by SWIG (http://www.swig.org). 3 * Version 2.0.11 4 * 5 * This file is not intended to be easily readable and contains a number of 6 * coding conventions designed to improve portability and efficiency. Do not make 7 * changes to this file unless you know what you are doing--modify the SWIG 8 * interface file instead. 9 * ----------------------------------------------------------------------------- */ 10 11 #define SWIGCSHARP 12 13 14 #ifdef __cplusplus 15 /* SwigValueWrapper is described in swig.swg */ 16 template<typename T> class SwigValueWrapper { 17 struct SwigMovePointer { 18 T *ptr; 19 SwigMovePointer(T *p) : ptr(p) { } 20 ~SwigMovePointer() { delete ptr; } 21 SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; } 22 } pointer; 23 SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs); 24 SwigValueWrapper(const SwigValueWrapper<T>& rhs); 25 public: 26 SwigValueWrapper() : pointer(0) { } 27 SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; } 28 operator T&() const { return *pointer.ptr; } 29 T *operator&() { return pointer.ptr; } 30 }; 31 32 template <typename T> T SwigValueInit() { 33 return T(); 34 } 35 #endif 36 37 /* ----------------------------------------------------------------------------- 38 * This section contains generic SWIG labels for method/variable 39 * declarations/attributes, and other compiler dependent labels. 40 * ----------------------------------------------------------------------------- */ 41 42 /* template workaround for compilers that cannot correctly implement the C++ standard */ 43 #ifndef SWIGTEMPLATEDISAMBIGUATOR 44 # if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) 45 # define SWIGTEMPLATEDISAMBIGUATOR template 46 # elif defined(__HP_aCC) 47 /* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ 48 /* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ 49 # define SWIGTEMPLATEDISAMBIGUATOR template 50 # else 51 # define SWIGTEMPLATEDISAMBIGUATOR 52 # endif 53 #endif 54 55 /* inline attribute */ 56 #ifndef SWIGINLINE 57 # if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) 58 # define SWIGINLINE inline 59 # else 60 # define SWIGINLINE 61 # endif 62 #endif 63 64 /* attribute recognised by some compilers to avoid 'unused' warnings */ 65 #ifndef SWIGUNUSED 66 # if defined(__GNUC__) 67 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) 68 # define SWIGUNUSED __attribute__ ((__unused__)) 69 # else 70 # define SWIGUNUSED 71 # endif 72 # elif defined(__ICC) 73 # define SWIGUNUSED __attribute__ ((__unused__)) 74 # else 75 # define SWIGUNUSED 76 # endif 77 #endif 78 79 #ifndef SWIG_MSC_UNSUPPRESS_4505 80 # if defined(_MSC_VER) 81 # pragma warning(disable : 4505) /* unreferenced local function has been removed */ 82 # endif 83 #endif 84 85 #ifndef SWIGUNUSEDPARM 86 # ifdef __cplusplus 87 # define SWIGUNUSEDPARM(p) 88 # else 89 # define SWIGUNUSEDPARM(p) p SWIGUNUSED 90 # endif 91 #endif 92 93 /* internal SWIG method */ 94 #ifndef SWIGINTERN 95 # define SWIGINTERN static SWIGUNUSED 96 #endif 97 98 /* internal inline SWIG method */ 99 #ifndef SWIGINTERNINLINE 100 # define SWIGINTERNINLINE SWIGINTERN SWIGINLINE 101 #endif 102 103 /* exporting methods */ 104 #if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) 105 # ifndef GCC_HASCLASSVISIBILITY 106 # define GCC_HASCLASSVISIBILITY 107 # endif 108 #endif 109 110 #ifndef SWIGEXPORT 111 # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 112 # if defined(STATIC_LINKED) 113 # define SWIGEXPORT 114 # else 115 # define SWIGEXPORT __declspec(dllexport) 116 # endif 117 # else 118 # if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) 119 # define SWIGEXPORT __attribute__ ((visibility("default"))) 120 # else 121 # define SWIGEXPORT 122 # endif 123 # endif 124 #endif 125 126 /* calling conventions for Windows */ 127 #ifndef SWIGSTDCALL 128 # if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) 129 # define SWIGSTDCALL __stdcall 130 # else 131 # define SWIGSTDCALL 132 # endif 133 #endif 134 135 /* Deal with Microsoft's attempt at deprecating C standard runtime functions */ 136 #if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) 137 # define _CRT_SECURE_NO_DEPRECATE 138 #endif 139 140 /* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ 141 #if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) 142 # define _SCL_SECURE_NO_DEPRECATE 143 #endif 144 145 146 147 #include <stdlib.h> 148 #include <string.h> 149 #include <stdio.h> 150 151 152 /* Support for throwing C# exceptions from C/C++. There are two types: 153 * Exceptions that take a message and ArgumentExceptions that take a message and a parameter name. */ 154 typedef enum { 155 SWIG_CSharpApplicationException, 156 SWIG_CSharpArithmeticException, 157 SWIG_CSharpDivideByZeroException, 158 SWIG_CSharpIndexOutOfRangeException, 159 SWIG_CSharpInvalidCastException, 160 SWIG_CSharpInvalidOperationException, 161 SWIG_CSharpIOException, 162 SWIG_CSharpNullReferenceException, 163 SWIG_CSharpOutOfMemoryException, 164 SWIG_CSharpOverflowException, 165 SWIG_CSharpSystemException 166 } SWIG_CSharpExceptionCodes; 167 168 typedef enum { 169 SWIG_CSharpArgumentException, 170 SWIG_CSharpArgumentNullException, 171 SWIG_CSharpArgumentOutOfRangeException 172 } SWIG_CSharpExceptionArgumentCodes; 173 174 typedef void (SWIGSTDCALL* SWIG_CSharpExceptionCallback_t)(const char *); 175 typedef void (SWIGSTDCALL* SWIG_CSharpExceptionArgumentCallback_t)(const char *, const char *); 176 177 typedef struct { 178 SWIG_CSharpExceptionCodes code; 179 SWIG_CSharpExceptionCallback_t callback; 180 } SWIG_CSharpException_t; 181 182 typedef struct { 183 SWIG_CSharpExceptionArgumentCodes code; 184 SWIG_CSharpExceptionArgumentCallback_t callback; 185 } SWIG_CSharpExceptionArgument_t; 186 187 static SWIG_CSharpException_t SWIG_csharp_exceptions[] = { 188 { SWIG_CSharpApplicationException, NULL }, 189 { SWIG_CSharpArithmeticException, NULL }, 190 { SWIG_CSharpDivideByZeroException, NULL }, 191 { SWIG_CSharpIndexOutOfRangeException, NULL }, 192 { SWIG_CSharpInvalidCastException, NULL }, 193 { SWIG_CSharpInvalidOperationException, NULL }, 194 { SWIG_CSharpIOException, NULL }, 195 { SWIG_CSharpNullReferenceException, NULL }, 196 { SWIG_CSharpOutOfMemoryException, NULL }, 197 { SWIG_CSharpOverflowException, NULL }, 198 { SWIG_CSharpSystemException, NULL } 199 }; 200 201 static SWIG_CSharpExceptionArgument_t SWIG_csharp_exceptions_argument[] = { 202 { SWIG_CSharpArgumentException, NULL }, 203 { SWIG_CSharpArgumentNullException, NULL }, 204 { SWIG_CSharpArgumentOutOfRangeException, NULL } 205 }; 206 207 static void SWIGUNUSED SWIG_CSharpSetPendingException(SWIG_CSharpExceptionCodes code, const char *msg) { 208 SWIG_CSharpExceptionCallback_t callback = SWIG_csharp_exceptions[SWIG_CSharpApplicationException].callback; 209 if ((size_t)code < sizeof(SWIG_csharp_exceptions)/sizeof(SWIG_CSharpException_t)) { 210 callback = SWIG_csharp_exceptions[code].callback; 211 } 212 callback(msg); 213 } 214 215 static void SWIGUNUSED SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpExceptionArgumentCodes code, const char *msg, const char *param_name) { 216 SWIG_CSharpExceptionArgumentCallback_t callback = SWIG_csharp_exceptions_argument[SWIG_CSharpArgumentException].callback; 217 if ((size_t)code < sizeof(SWIG_csharp_exceptions_argument)/sizeof(SWIG_CSharpExceptionArgument_t)) { 218 callback = SWIG_csharp_exceptions_argument[code].callback; 219 } 220 callback(msg, param_name); 221 } 222 223 224 #ifdef __cplusplus 225 extern "C" 226 #endif 227 SWIGEXPORT void SWIGSTDCALL SWIGRegisterExceptionCallbacks_MathLib( 228 SWIG_CSharpExceptionCallback_t applicationCallback, 229 SWIG_CSharpExceptionCallback_t arithmeticCallback, 230 SWIG_CSharpExceptionCallback_t divideByZeroCallback, 231 SWIG_CSharpExceptionCallback_t indexOutOfRangeCallback, 232 SWIG_CSharpExceptionCallback_t invalidCastCallback, 233 SWIG_CSharpExceptionCallback_t invalidOperationCallback, 234 SWIG_CSharpExceptionCallback_t ioCallback, 235 SWIG_CSharpExceptionCallback_t nullReferenceCallback, 236 SWIG_CSharpExceptionCallback_t outOfMemoryCallback, 237 SWIG_CSharpExceptionCallback_t overflowCallback, 238 SWIG_CSharpExceptionCallback_t systemCallback) { 239 SWIG_csharp_exceptions[SWIG_CSharpApplicationException].callback = applicationCallback; 240 SWIG_csharp_exceptions[SWIG_CSharpArithmeticException].callback = arithmeticCallback; 241 SWIG_csharp_exceptions[SWIG_CSharpDivideByZeroException].callback = divideByZeroCallback; 242 SWIG_csharp_exceptions[SWIG_CSharpIndexOutOfRangeException].callback = indexOutOfRangeCallback; 243 SWIG_csharp_exceptions[SWIG_CSharpInvalidCastException].callback = invalidCastCallback; 244 SWIG_csharp_exceptions[SWIG_CSharpInvalidOperationException].callback = invalidOperationCallback; 245 SWIG_csharp_exceptions[SWIG_CSharpIOException].callback = ioCallback; 246 SWIG_csharp_exceptions[SWIG_CSharpNullReferenceException].callback = nullReferenceCallback; 247 SWIG_csharp_exceptions[SWIG_CSharpOutOfMemoryException].callback = outOfMemoryCallback; 248 SWIG_csharp_exceptions[SWIG_CSharpOverflowException].callback = overflowCallback; 249 SWIG_csharp_exceptions[SWIG_CSharpSystemException].callback = systemCallback; 250 } 251 252 #ifdef __cplusplus 253 extern "C" 254 #endif 255 SWIGEXPORT void SWIGSTDCALL SWIGRegisterExceptionArgumentCallbacks_MathLib( 256 SWIG_CSharpExceptionArgumentCallback_t argumentCallback, 257 SWIG_CSharpExceptionArgumentCallback_t argumentNullCallback, 258 SWIG_CSharpExceptionArgumentCallback_t argumentOutOfRangeCallback) { 259 SWIG_csharp_exceptions_argument[SWIG_CSharpArgumentException].callback = argumentCallback; 260 SWIG_csharp_exceptions_argument[SWIG_CSharpArgumentNullException].callback = argumentNullCallback; 261 SWIG_csharp_exceptions_argument[SWIG_CSharpArgumentOutOfRangeException].callback = argumentOutOfRangeCallback; 262 } 263 264 265 /* Callback for returning strings to C# without leaking memory */ 266 typedef char * (SWIGSTDCALL* SWIG_CSharpStringHelperCallback)(const char *); 267 static SWIG_CSharpStringHelperCallback SWIG_csharp_string_callback = NULL; 268 269 270 #ifdef __cplusplus 271 extern "C" 272 #endif 273 SWIGEXPORT void SWIGSTDCALL SWIGRegisterStringCallback_MathLib(SWIG_CSharpStringHelperCallback callback) { 274 SWIG_csharp_string_callback = callback; 275 } 276 277 278 /* Contract support */ 279 280 #define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, msg, ""); return nullreturn; } else 281 282 283 #include "Math.h" 284 285 286 #ifdef __cplusplus 287 extern "C" { 288 #endif 289 290 SWIGEXPORT void * SWIGSTDCALL CSharp_new_CMath() { 291 void * jresult ; 292 CMath *result = 0 ; 293 294 result = (CMath *)new CMath(); 295 jresult = (void *)result; 296 return jresult; 297 } 298 299 300 SWIGEXPORT void SWIGSTDCALL CSharp_delete_CMath(void * jarg1) { 301 CMath *arg1 = (CMath *) 0 ; 302 303 arg1 = (CMath *)jarg1; 304 delete arg1; 305 } 306 307 308 SWIGEXPORT int SWIGSTDCALL CSharp_CMath_Add(void * jarg1, int jarg2, int jarg3) { 309 int jresult ; 310 CMath *arg1 = (CMath *) 0 ; 311 int arg2 ; 312 int arg3 ; 313 int result; 314 315 arg1 = (CMath *)jarg1; 316 arg2 = (int)jarg2; 317 arg3 = (int)jarg3; 318 result = (int)(arg1)->Add(arg2,arg3); 319 jresult = result; 320 return jresult; 321 } 322 323 324 SWIGEXPORT void SWIGSTDCALL CSharp_CMath_n_set(void * jarg1, int jarg2) { 325 CMath *arg1 = (CMath *) 0 ; 326 int arg2 ; 327 328 arg1 = (CMath *)jarg1; 329 arg2 = (int)jarg2; 330 if (arg1) (arg1)->n = arg2; 331 } 332 333 334 SWIGEXPORT int SWIGSTDCALL CSharp_CMath_n_get(void * jarg1) { 335 int jresult ; 336 CMath *arg1 = (CMath *) 0 ; 337 int result; 338 339 arg1 = (CMath *)jarg1; 340 result = (int) ((arg1)->n); 341 jresult = result; 342 return jresult; 343 } 344 345 346 #ifdef __cplusplus 347 } 348 #endif