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

1 /* ---------------------------------------------------------------------------- 2 * This file was automatically generated by SWIG (http://www.swig.org). 3 * Version 2.0.11 4 * 5 * Do not make changes to this file unless you know what you are doing--modify 6 * the SWIG interface file instead. 7 * ----------------------------------------------------------------------------- */ 8 9 10 using System; 11 using System.Runtime.InteropServices; 12 13 public class CMath : IDisposable { 14 private HandleRef swigCPtr; 15 protected bool swigCMemOwn; 16 17 internal CMath(IntPtr cPtr, bool cMemoryOwn) { 18 swigCMemOwn = cMemoryOwn; 19 swigCPtr = new HandleRef(this, cPtr); 20 } 21 22 internal static HandleRef getCPtr(CMath obj) { 23 return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; 24 } 25 26 ~CMath() { 27 Dispose(); 28 } 29 30 public virtual void Dispose() { 31 lock(this) { 32 if (swigCPtr.Handle != IntPtr.Zero) { 33 if (swigCMemOwn) { 34 swigCMemOwn = false; 35 MathLibPINVOKE.delete_CMath(swigCPtr); 36 } 37 swigCPtr = new HandleRef(null, IntPtr.Zero); 38 } 39 GC.SuppressFinalize(this); 40 } 41 } 42 43 public CMath() : this(MathLibPINVOKE.new_CMath(), true) { 44 } 45 46 public int Add(int a, int b) { 47 int ret = MathLibPINVOKE.CMath_Add(swigCPtr, a, b); 48 return ret; 49 } 50 51 public int n { 52 set { 53 MathLibPINVOKE.CMath_n_set(swigCPtr, value); 54 } 55 get { 56 int ret = MathLibPINVOKE.CMath_n_get(swigCPtr); 57 return ret; 58 } 59 } 60 61 }

1 /* ---------------------------------------------------------------------------- 2 * This file was automatically generated by SWIG (http://www.swig.org). 3 * Version 2.0.11 4 * 5 * Do not make changes to this file unless you know what you are doing--modify 6 * the SWIG interface file instead. 7 * ----------------------------------------------------------------------------- */ 8 9 10 using System; 11 using System.Runtime.InteropServices; 12 13 public class MathLib { 14 }

1 /* ---------------------------------------------------------------------------- 2 * This file was automatically generated by SWIG (http://www.swig.org). 3 * Version 2.0.11 4 * 5 * Do not make changes to this file unless you know what you are doing--modify 6 * the SWIG interface file instead. 7 * ----------------------------------------------------------------------------- */ 8 9 10 using System; 11 using System.Runtime.InteropServices; 12 13 class MathLibPINVOKE { 14 15 protected class SWIGExceptionHelper { 16 17 public delegate void ExceptionDelegate(string message); 18 public delegate void ExceptionArgumentDelegate(string message, string paramName); 19 20 static ExceptionDelegate applicationDelegate = new ExceptionDelegate(SetPendingApplicationException); 21 static ExceptionDelegate arithmeticDelegate = new ExceptionDelegate(SetPendingArithmeticException); 22 static ExceptionDelegate divideByZeroDelegate = new ExceptionDelegate(SetPendingDivideByZeroException); 23 static ExceptionDelegate indexOutOfRangeDelegate = new ExceptionDelegate(SetPendingIndexOutOfRangeException); 24 static ExceptionDelegate invalidCastDelegate = new ExceptionDelegate(SetPendingInvalidCastException); 25 static ExceptionDelegate invalidOperationDelegate = new ExceptionDelegate(SetPendingInvalidOperationException); 26 static ExceptionDelegate ioDelegate = new ExceptionDelegate(SetPendingIOException); 27 static ExceptionDelegate nullReferenceDelegate = new ExceptionDelegate(SetPendingNullReferenceException); 28 static ExceptionDelegate outOfMemoryDelegate = new ExceptionDelegate(SetPendingOutOfMemoryException); 29 static ExceptionDelegate overflowDelegate = new ExceptionDelegate(SetPendingOverflowException); 30 static ExceptionDelegate systemDelegate = new ExceptionDelegate(SetPendingSystemException); 31 32 static ExceptionArgumentDelegate argumentDelegate = new ExceptionArgumentDelegate(SetPendingArgumentException); 33 static ExceptionArgumentDelegate argumentNullDelegate = new ExceptionArgumentDelegate(SetPendingArgumentNullException); 34 static ExceptionArgumentDelegate argumentOutOfRangeDelegate = new ExceptionArgumentDelegate(SetPendingArgumentOutOfRangeException); 35 36 [DllImport("MathLib", EntryPoint="SWIGRegisterExceptionCallbacks_MathLib")] 37 public static extern void SWIGRegisterExceptionCallbacks_MathLib( 38 ExceptionDelegate applicationDelegate, 39 ExceptionDelegate arithmeticDelegate, 40 ExceptionDelegate divideByZeroDelegate, 41 ExceptionDelegate indexOutOfRangeDelegate, 42 ExceptionDelegate invalidCastDelegate, 43 ExceptionDelegate invalidOperationDelegate, 44 ExceptionDelegate ioDelegate, 45 ExceptionDelegate nullReferenceDelegate, 46 ExceptionDelegate outOfMemoryDelegate, 47 ExceptionDelegate overflowDelegate, 48 ExceptionDelegate systemExceptionDelegate); 49 50 [DllImport("MathLib", EntryPoint="SWIGRegisterExceptionArgumentCallbacks_MathLib")] 51 public static extern void SWIGRegisterExceptionCallbacksArgument_MathLib( 52 ExceptionArgumentDelegate argumentDelegate, 53 ExceptionArgumentDelegate argumentNullDelegate, 54 ExceptionArgumentDelegate argumentOutOfRangeDelegate); 55 56 static void SetPendingApplicationException(string message) { 57 SWIGPendingException.Set(new System.ApplicationException(message, SWIGPendingException.Retrieve())); 58 } 59 static void SetPendingArithmeticException(string message) { 60 SWIGPendingException.Set(new System.ArithmeticException(message, SWIGPendingException.Retrieve())); 61 } 62 static void SetPendingDivideByZeroException(string message) { 63 SWIGPendingException.Set(new System.DivideByZeroException(message, SWIGPendingException.Retrieve())); 64 } 65 static void SetPendingIndexOutOfRangeException(string message) { 66 SWIGPendingException.Set(new System.IndexOutOfRangeException(message, SWIGPendingException.Retrieve())); 67 } 68 static void SetPendingInvalidCastException(string message) { 69 SWIGPendingException.Set(new System.InvalidCastException(message, SWIGPendingException.Retrieve())); 70 } 71 static void SetPendingInvalidOperationException(string message) { 72 SWIGPendingException.Set(new System.InvalidOperationException(message, SWIGPendingException.Retrieve())); 73 } 74 static void SetPendingIOException(string message) { 75 SWIGPendingException.Set(new System.IO.IOException(message, SWIGPendingException.Retrieve())); 76 } 77 static void SetPendingNullReferenceException(string message) { 78 SWIGPendingException.Set(new System.NullReferenceException(message, SWIGPendingException.Retrieve())); 79 } 80 static void SetPendingOutOfMemoryException(string message) { 81 SWIGPendingException.Set(new System.OutOfMemoryException(message, SWIGPendingException.Retrieve())); 82 } 83 static void SetPendingOverflowException(string message) { 84 SWIGPendingException.Set(new System.OverflowException(message, SWIGPendingException.Retrieve())); 85 } 86 static void SetPendingSystemException(string message) { 87 SWIGPendingException.Set(new System.SystemException(message, SWIGPendingException.Retrieve())); 88 } 89 90 static void SetPendingArgumentException(string message, string paramName) { 91 SWIGPendingException.Set(new System.ArgumentException(message, paramName, SWIGPendingException.Retrieve())); 92 } 93 static void SetPendingArgumentNullException(string message, string paramName) { 94 Exception e = SWIGPendingException.Retrieve(); 95 if (e != null) message = message + " Inner Exception: " + e.Message; 96 SWIGPendingException.Set(new System.ArgumentNullException(paramName, message)); 97 } 98 static void SetPendingArgumentOutOfRangeException(string message, string paramName) { 99 Exception e = SWIGPendingException.Retrieve(); 100 if (e != null) message = message + " Inner Exception: " + e.Message; 101 SWIGPendingException.Set(new System.ArgumentOutOfRangeException(paramName, message)); 102 } 103 104 static SWIGExceptionHelper() { 105 SWIGRegisterExceptionCallbacks_MathLib( 106 applicationDelegate, 107 arithmeticDelegate, 108 divideByZeroDelegate, 109 indexOutOfRangeDelegate, 110 invalidCastDelegate, 111 invalidOperationDelegate, 112 ioDelegate, 113 nullReferenceDelegate, 114 outOfMemoryDelegate, 115 overflowDelegate, 116 systemDelegate); 117 118 SWIGRegisterExceptionCallbacksArgument_MathLib( 119 argumentDelegate, 120 argumentNullDelegate, 121 argumentOutOfRangeDelegate); 122 } 123 } 124 125 protected static SWIGExceptionHelper swigExceptionHelper = new SWIGExceptionHelper(); 126 127 public class SWIGPendingException { 128 [ThreadStatic] 129 private static Exception pendingException = null; 130 private static int numExceptionsPending = 0; 131 132 public static bool Pending { 133 get { 134 bool pending = false; 135 if (numExceptionsPending > 0) 136 if (pendingException != null) 137 pending = true; 138 return pending; 139 } 140 } 141 142 public static void Set(Exception e) { 143 if (pendingException != null) 144 throw new ApplicationException("FATAL: An earlier pending exception from unmanaged code was missed and thus not thrown (" + pendingException.ToString() + ")", e); 145 pendingException = e; 146 lock(typeof(MathLibPINVOKE)) { 147 numExceptionsPending++; 148 } 149 } 150 151 public static Exception Retrieve() { 152 Exception e = null; 153 if (numExceptionsPending > 0) { 154 if (pendingException != null) { 155 e = pendingException; 156 pendingException = null; 157 lock(typeof(MathLibPINVOKE)) { 158 numExceptionsPending--; 159 } 160 } 161 } 162 return e; 163 } 164 } 165 166 167 protected class SWIGStringHelper { 168 169 public delegate string SWIGStringDelegate(string message); 170 static SWIGStringDelegate stringDelegate = new SWIGStringDelegate(CreateString); 171 172 [DllImport("MathLib", EntryPoint="SWIGRegisterStringCallback_MathLib")] 173 public static extern void SWIGRegisterStringCallback_MathLib(SWIGStringDelegate stringDelegate); 174 175 static string CreateString(string cString) { 176 return cString; 177 } 178 179 static SWIGStringHelper() { 180 SWIGRegisterStringCallback_MathLib(stringDelegate); 181 } 182 } 183 184 static protected SWIGStringHelper swigStringHelper = new SWIGStringHelper(); 185 186 187 static MathLibPINVOKE() { 188 } 189 190 191 [DllImport("MathLib", EntryPoint="CSharp_new_CMath")] 192 public static extern IntPtr new_CMath(); 193 194 [DllImport("MathLib", EntryPoint="CSharp_delete_CMath")] 195 public static extern void delete_CMath(HandleRef jarg1); 196 197 [DllImport("MathLib", EntryPoint="CSharp_CMath_Add")] 198 public static extern int CMath_Add(HandleRef jarg1, int jarg2, int jarg3); 199 200 [DllImport("MathLib", EntryPoint="CSharp_CMath_n_set")] 201 public static extern void CMath_n_set(HandleRef jarg1, int jarg2); 202 203 [DllImport("MathLib", EntryPoint="CSharp_CMath_n_get")] 204 public static extern int CMath_n_get(HandleRef jarg1); 205 }
4.在Vc项目中添加Test_wrap.cxx,编译。生成dll :MathLib.dll。拷贝到新建的C#项目运行目录下。
5.在C#项目中添加CMath.cs,MathLib.cs和MathLibPINVOKE.cs,可以直接编译C#的Dll,也可以直接调用CMath的CLR类。
C#调用代码:

1 private void button1_Click(object sender, EventArgs e) 2 { 3 CMath math = new CMath(); 4 int c=math.Add(10, 23); 5 MessageBox.Show(c.ToString()); 6 7 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律