1. 不返回值的参数
C++ 原型: bool SendNewSms(char *szTel, char *szMessage);
C#引用;
[DllImport( "CdmaCard.dll",EntryPoint="SendNewSms")]
public static extern bool SendNewSms(string phone,string msg);
2. 带返回值(char *)
C++原型:
BOOL GetCardErrorMessage(char *szErrorMessage , int errorCode);
C#引用[DllImport( "CdmaCard.dll",EntryPoint="GetCardErrorMessage")]
public static extern int GetCardErrorMessage(StringBuilder msg,int errorCode);
StringBuilder buf = new StringBuilder(1024);//指定的Buf大小必须大于可能的最大长度
GetCardErrorMessage(buf,1);
3. 带返回值(其他类型)
C++原型:
BOOL GetSmsSaveStation (int *nSmsStation);
C#引用
- []
- public static extern bool GetSmsSaveStation(ref int nStation);
4. 传递结构体指针(C++填充)
C++原型:
C++中结构体定义
typedef struct // 平面
{
double time;
float normal[3];
float center[3];
} plane;
C++中方法声明:
public void GetPlanes(plane *planes, int size);
C#引用
C#中结构体声明:
[StructLayout(LayoutKind.Sequential)]
public struct GPlane
{
public double timestamp;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] normal;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public float[] center;
}
C#中方法声明:
[DllImport(LibFileName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern bool Pvr_getAirGlassPlanes([In, Out]GPlane[] plane, int size);
C#中调用该方法:int size = 2;
GPlane[] plane = new GPlane[size];
Pvr_getAirGlassPlanes(plane, size);
5. 传递结构体数组(C++来填充)
C++原型:
- struct UIM_BOOK_STRUCT
- {
- int UimIndex;
- char szName[15];
- char szPhone[21];
- };
- int ReadUimAllBook(UIM_BOOK_STRUCT lpUimBookItem[],int nMaxArraySize);
C#引用
- [//可以指定编码类型]
- public struct UIM_BOOK_STRUCT
- {
- public int UimIndex;
- []
- public string szName;
- []
- public string szPhone;
- };
- []
- public static extern int ReadUimAllBook([Out] UIM_BOOK_STRUCT [] lpUimBookItem,int nMaxArraySize);
- UIM_BOOK_STRUCT[] p = new UIM_BOOK_STRUCT[20];
- int ret = ReadUimAllBook(p,p.Length);
6. 注意问题
类型不一致,会导致调用失败,
(1) long 类型,在C++中是4字节的整数,在C#中是8字节的整数;
(2) 字符串类型的设置不正确;
以下是几个简单的window调用
- [// We won't use this maliciously]
- []
- public static extern bool ScreenToClient(IntPtr hWnd, ref System.Drawing.Point rect);
- [// We won't use this maliciously]
- []
- public static extern bool GetWindowRect(IntPtr hWnd, out System.Drawing.Rectangle rect);
- [// We won't use this maliciously]
- []
- public static extern bool UnregisterClass([MarshalAs(UnmanagedType.LPTStr)] string className, IntPtr instanceHandle);
C#调用C++DLL类库中的类的方法
1. 方式1
2. 方式2
The only way to directly call methods on a C++ object from C# (and most other languages) is to create a full-fledged COM object out of it.
An easier way with a level of indirection: Develop an API of purely static methods that reflect the object's operations. Then you can call that from .NET easily.
C++
MyClass* WINAPI CreateMyClass() { return new MyClass(); }
void WINAPI CallFoo(MyClass* o) { o->foo(); }
C#
[DllImport("MyDLL")]
private static IntPtr CreateMyClass();
[DllImport("MyDLL")]
private static void CallFoo(IntPtr o);