本文转载至http://www.cnblogs.com/ysharp/archive/2012/05/25/2517803.html

在合作开发时,C#时常需要调用C++DLL,当传递参数时时常遇到问题,尤其是传递和返回字符串是,现总结一下,分享给大家:

VC++中主要字符串类型为:LPSTR,LPCSTR, LPCTSTR, string, CString, LPCWSTR, LPWSTR等
但转为C#类型却不完全相同。

主要有如下几种转换:

将string转为IntPtr:IntPtr System.Runtime.InteropServices.Marshal.StringToCoTaskMemAuto(string)

将IntPtr转为string:string System.Runtime.InteropServices.MarshalPtrToStringAuto(IntPtr)

类型对照:

BSTR ---------  StringBuilder

LPCTSTR --------- StringBuilder

LPCWSTR ---------  IntPtr

handle---------IntPtr

hwnd-----------IntPtr

char *----------string

int * -----------ref int

int &-----------ref int

void *----------IntPtr

unsigned char *-----ref byte

Struct需要在C#里重新定义一个Struct

CallBack回调函数需要封装在一个委托里,delegate static extern int FunCallBack(string str);

注意在每个函数的前面加上public static extern +返回的数据类型,如果不加public ,函数默认为私有函数,调用就会出错。

在C#调用C++ DLL封装库时会出现两个问题:

1. 数据类型转换问题
2. 指针或地址参数传送问题

首先是数据类型转换问题。因为C#是.NET语言,利用的是.NET的基本数据类型,所以实际上是将C++的数据类型与.NET的基本数据类型进行对应。

例如C++的原有函数是:

int __stdcall FunctionName(unsigned char param1, unsigned short param2)

其中的参数数据类型在C#中,必须转为对应的数据类型。如:

[DllImport(“ COM DLL path/file ”)]
extern static int FunctionName(byte param1, ushort param2)

因为调用的是__stdcall函数,所以使用了P/Invoke的调用方法。其中的方法FunctionName必须声明为静态外部函数,即加上extern static声明头。我们可以看到,在调用的过程中,unsigned char变为了byte,unsigned short变为了ushort。变换后,参数的数据类型不变,只是声明方式必须改为.NET语言的规范。

我们可以通过下表来进行这种转换:

Win32 Types
CLR Type

char, INT8, SBYTE, CHAR
System.SByte

short, short int, INT16, SHORT
System.Int16

int, long, long int, INT32, LONG32, BOOL , INT
System.Int32

__int64, INT64, LONGLONG
System.Int64

unsigned char, UINT8, UCHAR , BYTE
System.Byte

unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR , __wchar_t
System.UInt16

unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT
System.UInt32

unsigned __int64, UINT64, DWORDLONG, ULONGLONG
System.UInt64

float, FLOAT
System.Single

double, long double, DOUBLE
System.Double

之后再将CLR的数据类型表示方式转换为C#的表示方式。这样一来,函数的参数类型问题就可以解决了。

现在,我们再来考虑下一个问题,如果要调用的函数参数是指针或是地址变量,怎么办?

对于这种情况可以使用C#提供的非安全代码来进行解决,但是,毕竟是非托管代码,垃圾资源处理不好的话对应用程序是很不利的。所以还是使用C#提供的ref以及out修饰字比较好。

同上面一样,我们也举一个例子:

int __stdcall FunctionName(unsigned char &param1, unsigned char *param2)

在C#中对其进行调用的方法是:

[DllImport(“ file ”)]
extern static int FunctionName(ref byte param1, ref byte param2)

看到这,可能有人会问,&是取地址,*是传送指针,为何都只用ref就可以了呢?一种可能的解释是ref是一个具有重载特性的修饰符,会自动识别是取地址还是传送指针。

在实际的情况中,我们利用参数传递地址更多还是用在传送数组首地址上。
如:byte[] param1 = new param1(6);

在这里我们声明了一个数组,现在要将其的首地址传送过去,只要将param1数组的第一个元素用ref修饰。具体如下:

[DllImport(“ file ”)]
extern static int FunctionName(ref byte param1[1], ref byte param2)
 
文章出处:DIY部落(http://www.diybl.com/course/3_program/c++/cppjs/200886/134816.html)

C# 中调用DLL
为了能用上原来的C++代码,只好研究下从C# 中调用DLL
首先必须要有一个声明,使用的是DllImport关键字:
包含DllImport所在的名字空间
using System.Runtime.InteropServices;
public class XXXX{

[DllImport(“MyDLL.dll")]
public static extern int mySum (int a,int b);
}

[DllImport(“MyDLL.dll")]
public static extern int mySum (int a,int b);
代码中DllImport关键字作用是告诉编译器入口点在哪里,并将打包函数捆绑在这个类中
在调用的时候
在类中的时候 直接   mySum(a,b);就可以了
在其他类中调用: XXXX. mySum(a,b);
 
[DllImport(“MyDLL.dll”)]在申明的时候还可以添加几个属性
[DllImport(“MyDLL.dll", EntryPoint=" mySum ",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)
]
EntryPoint: 指定要调用的 DLL 入口点。默认入口点名称是托管方法的名称 。
CharSet: 控制名称重整和封送 String 参数的方式 (默认是UNICODE)
CallingConvention指示入口点的函数调用约定(默认WINAPI)(上次报告讲过的)
SetLastError 指示被调用方在从属性化方法返回之前是否调用 SetLastError Win32 API 函数 (C#中默认false )

int 类型
[DllImport(“MyDLL.dll")]
//返回个int 类型
public static extern int mySum (int a1,int b1);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(int a2,int b2)
{
//a2 b2不能改变a1 b1
//a2=..
//b2=...
 return a+b;
}

//参数传递int 类型
public static extern int mySum (ref int a1,ref int b1);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(int *a2,int *b2)
{
//可以改变 a1, b1
*a2=...
*b2=...
 return a+b;
}

DLL 需传入char *类型
[DllImport(“MyDLL.dll")]
//传入值
public static extern int mySum (string  astr1,string bstr1);
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(char * astr2,char * bstr2)
{
//改变astr2 bstr 2  ,astr1 bstr1不会被改变
 return a+b;
}

DLL 需传出char *类型
[DllImport(“MyDLL.dll")]
// 传出值
public static extern int mySum (StringBuilder abuf, StringBuilder bbuf );
//DLL中申明
extern “C” __declspec(dllexport)  int WINAPI mySum(char * astr,char * bstr)
{
//传出char * 改变astr bstr -->abuf, bbuf可以被改变
 return a+b;
}
 
DLL 回调函数

BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)

using System;
using System.Runtime.InteropServices;
public delegate bool CallBack(int hwnd, int lParam); //定义委托函数类型
public class EnumReportApp
{
[DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y);
public static void Main() {
CallBack myCallBack = new CallBack(EnumReportApp.Report); EnumWindows(myCallBack, 0);
}
public static bool Report(int hwnd, int lParam)
{
Console.Write("Window handle is ");
Console.WriteLine(hwnd); return true;
}
}

DLL  传递结构
BOOL PtInRect(const RECT *lprc, POINT pt);

using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct Point {
 public int x;
public int y;
 }
[StructLayout(LayoutKind.Explicit)]
 public struct Rect
 {
[FieldOffset(0)] public int left;
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right;
[FieldOffset(12)] public int bottom;
 }
Class XXXX {
 [DllImport("User32.dll")]
public static extern bool PtInRect(ref  Rect r, Point p);
 }

DLL 回调函数,传递结构 想看的msdn里面都有专题介绍,看的我都是晕晕的:)

其他参考请搜索:

在C#程序设计中使用Win32类库
C#中调用C++托管Dll
如何在C#中加载自己编写的动态链接库

相关文章:Creating a P/Invoke Library

能用上DLL以后感觉还是很好的,原来的C++代码只要修改编译通过就可以了,
高兴没多久,发现.net2005居然可以用VB,VC开发智能设备项目,可以创建MFC智能设备项目
晕晕,难道可以直接用MFC来开发smartphone的程序了,赶紧看看,,,

Visual C++ 使用 __declspec(dllexport) 从 DLL 导出 (到C#)
由于各种的原因, 如何把unmanaged 的 c++ DLL 转换成 managed C# 是一个问题。

方法有3个.

Ø 使用.def文件

Ø 可以不用.def文件, 使用__declspec(dllexport)关键字, 特别是针对Visual C++编译器的时候

Ø 直接用MC++写

什么时候用.def文件?

.def的意思是module-definition, 这个纯文本的文件定义了模块的信息。 对于编译器来说, 一个方法在编译之后的DLL文件里, 存在的形式名字可能不是作者当时起的那个,例如好好的函数名字function() 变成了?function2@@YAXXZ; 可以用undname查看这个被编译器修饰掉的名字, 原型是"void __cdecl function2(void)". 大概使用的时候就会遇到类似”链接错误,未决的外部符号…” 的错误.

.def文件主要的作用, 就是”标注” 出这个函数原来的样子, 这样编译器在编译的时候, 规则上就会以C编译器的规则来处理, 修饰被去掉了, 另外同时可以把导出函数的序号值手动的改高一点; 还有一个优点(也是缺点) 就是可以用NONAME来修饰函数, 这样导出函数的序号值就变成了1~N, 即第N个函数. 所以调用GetProcAddress() 的时候, 可以直接用定义的序号值, 而不用写函数的名字(但是名字就完全不可用了), 更好的是, 导出函数的这个DLL会变得比较小, 当然, MSDN强调了一点: 仅你可以并有权更改这个.def文件内容的时候, 你才可以用这个办法.

那么, 什么时候考虑用.def文件呢? 因为编译器不同, 而产生的修饰名不同的话, 这个文件就是必须的.

注意如果文件没有导出函数的话, 这个文件可能降低运行效率。

.def文件的格式

LIBRARY FileNameWithoutExtension

EXPORTS

Function1 @1

Function3 @2

Function2 @3 NONAME

启用 Enable it: Property pages-> Configuration Properties->C/C++ -> Linker -> input -> Module Definition File

那不用.def呢? __declspec(dllexport)的作用

这个东西, 可以给函数用, 也可以给类用. 声明大概这样子:

view source
< id="highlighter_930381_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 __declspec(dllexport) int __stdcall GetMid(vector<type> ve);

2 class __declspec(dllexport) TestClass{

3 public :

4 TestClass();

5 }

这牵扯到了一个东西就是__stdcall和__cdecl (还有__fastcall, 不过很少用), 其中__cdecl一般是C或者C++的缺省调用规范, 但是最大的一个区别就是__stdcall在返回前自身清除堆栈, 而__cdecl是调用方来做这个事情(可参考COM中的某些机制), 另一个区别就是__stdcall对于可变参数的函数, 玩不转.

反正今时今日, 大家都在用__stdcall, 所以这么写也没什么问题, 但不是没有. VB里调用标记着__cdecl的方法, 可能会得到一个异常Bad DLL Calling Convention. 解决方法也很简单:

原来的函数

view source
< id="highlighter_718220_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 long _cdecl PassStr(LPSTR pStr)

2 {       return 1;      }

新的函数

view source
< id="highlighter_515163_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 long _stdcall PassStrStdCall(LPSTR pStr)

2 {       return PassStr(pStr);      }

问题是, 如果这个函数原型, 参数是可变的, 那又怎么弄呢?

调用的时候, C#都是这么写的:

view source
< id="highlighter_120154_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 [DllImport("", EntryPoint = @" ?GetMid@@YAXXZ", CharSet = CharSet.Auto)]

2 private static extern void GetMid(...);

这个入口点名字还真别扭, 看来去掉这个修饰还是蛮需要的, 除了用.def文件, 另一个办法就是用 extern “C”.

Extern “C”

一句话总结:这个东西可以去掉修饰名。在不用.def文件的前提下, 这个可以保证你的函数function() 还是这个名字.

但是,这个东西对类不太起作用!

这个东西是这么用的: 放到函数声明的最前面。 就类似这样 extern “C” void __declspec(dllexport) function(void);

对于类, 一般的做法是, 把它的内部方法(特别是实例方法,或变量),wrap出一个方法来。 见下面的实例.

还要做什么?

当一个DLL被初始化的时候, 它需要一个入口点, 一般对于非MFC DLL来说, 这样写就行了:

view source
< id="highlighter_702691_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
01 BOOL APIENTRY DllMain(HANDLE hModule,

02                       DWORD  ul_reason_for_call,

03                       LPVOID lpReserved

04                       )

05 {

06     switch( ul_reason_for_call )

07     {

08     case DLL_PROCESS_ATTACH:

09     case DLL_THREAD_ATTACH:

10     case DLL_THREAD_DETACH:

11     case DLL_PROCESS_DETACH:

12         break;

13     }

14     return TRUE;

15 }

要注意的是这个入口点的名字必须是DllMain, 如果不是需要修改linker的/entry 选项. 否则对于C的话可能会初始化失败.

************************************************************************

开始用导出函数 PInvoke

为了好看一点, 先约定一下:

view source
< id="highlighter_95255_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 #define EXT_C extern "C"

2 #define DLLEXPORT __declspec(dllexport)

3 #define EXT_C_DLLEXPORT EXT_C DLLEXPORT

4 #define CALLBACK    __stdcall

5 #define WINAPI      __stdcall

6 #define APIENTRY    WINAPI

1. 普通的函数

view source
< id="highlighter_171056_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 EXT_C_DLLEXPORT void WINAPI Function();

2

3 [DllImport("filename.dll", EntryPoint = " Function")]

4 private static extern void Func();

2. ref或者out

view source
< id="highlighter_733498_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 EXT_C_DLLEXPORT void WINAPI Function(Type** ty);

2

3 [DllImport("filename.dll", EntryPoint = " Function")]

4 private static extern void Func(out Type ty);

3. 指针函数和委托

view source
< id="highlighter_987259_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 Typedef void (CALLBACK *pFunc)(int);

2 EXT_C_DLLEXPORT void WINAPI Compare(int a, int b, pFunc p);

3 private delegate int CompareCallback(int a, int b);

4 [DllImport("filename.dll",EntryPoint=”Compare”)]

5 private static extern int Compare(int a, int b, CompareCallback call);

4. 类的处理. 其实不是说不可以把类标记为 DLLEXPORT, 如果可以的话, 当然是wrap比较好

C++里的原型

view source
< id="highlighter_909839_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 class DLLEXPORT Test

2 {

3 public :

4     Test();

5     ~Test();

6     BOOL function(int par)

7 };

类被export, 函数调用时候注意用CallingConvention.ThisCall.

view source
< id="highlighter_447728_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 [DllImport("filename.dll", EntryPoint = @"??4Test@@QEAAAEAV0@AEBV0@@Z", CallingConvention = CallingConvention.ThisCall)]

2   private static extern int TestFunc(IntPtr hwnd, int par);

采用了”迂回”策略, C++里先这样定义,同理, 添加构造函数等, 函数就变成了这个样子:

view source
< id="highlighter_371353_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
01 EXT_C_DLLEXPORT BOOL WINAPI function_wrap(Test* t, int par)

02 {

03     return t->function(par);

04 }

05 EXT_C_DLLEXPORT Test* Test_ctor()

06 {

07     Test* t = new Test();

08     return t;

09 }

10 EXT_C_DLLEXPORT void Test_dector(Test* t)

11 {

12     if(NULL == t)

13     {

14         delete t;

15         t = NULL;

16     }

17 }

在C#里这样写, 那么就和平时用没什么区别了.

view source
< id="highlighter_413990_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
01 public class Test : IDisposable

02         {

03             private IntPtr instance;

04             public Test()

05             {

06                 instance = CreateInstance();

07             }

08

09              ~Test()

10             {

11                 Dispose(false);

12             }

13

14             #region pinvoke

15             [DllImport("filename.dll", EntryPoint = @"Test_ctor")]

16             private static extern IntPtr CreateInstance();

17             [DllImport("filename.dll", EntryPoint = @"Test_dector")]

18             private static extern void DestroyInstance(IntPtr hwnd);

19             [return: MarshalAs(UnmanagedType.Bool)]

20             [DllImport("filename.dll", EntryPoint = @"function_wrap")]

21             private static extern bool function_wrap(int par);

22             #endregion

23

24             #region IDisposable Members

25

26             public void Dispose()

27             {

28                 Dispose(true);

29             }

30

31             private void Dispose(bool bDisposing)

32             {

33                 if (instance != IntPtr.Zero)

34                 {

35                     DestroyInstance(instance);

36                 }

37

38                 if (bDisposing)

39                 {

40                     GC.SuppressFinalize(this);

41                 }

42             }

43

44             #endregion

45         }

5. Struct操作.

view source
< id="highlighter_777150_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 typedef struct Object_HANDLE {

2   unsigned long      dbch_size;

3   HANDLE     dbch_handle;

4   GUID       dbch_eventguid;

5   BOOL res_flag;

6 } Object_Native_HANDLE ;

首先在C#里严格定义这个,LayoutKind.Sequential 用来保证内存分配的正常。

view source
< id="highlighter_876084_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 [StructLayout(LayoutKind.Sequential)]

2 public struct Object_Native_HANDLE

3 {

4     public ulong dbch_size;

5     public IntPtr dbch_handle;

6     public Guid dbch_eventGuid;

7     public bool res_flag;

8 }

Marshal的使用如下:

view source
< id="highlighter_487393_clipboard" title="copy to clipboard" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="16" height="16" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" type="application/x-shockwave-flash">
print?
1 Object_Native_HANDLE obj = new Object_Native_HANDLE(); //初始化

2 int amountToAllocate = Marshal.SizeOf(obj);//获取大小

3 IntPtr objPtr = Marshal.AllocHGlobal(amountToAllocate); //分配并获取空的空间地址

4 Marshal.StructureToPtr(obj, objPtr, false); // 值写入分配的空间

5 //操作...

6 Marshal.FreeHGlobal(objPtr);//释放空间

最后提一句, unmaged code中的错误, 到managed 以后, 极大可能是捕捉不到的。 所以错误需要分别处理。

花了不少时间, MC++平时用的不多, 不写了。

[转]C#调用C++dll的更多相关文章

  1. c# 调用c++DLL方法及注意事项

    引用命名空间 using System.Runtime.InteropServices 调用方法: 一.静态加载 用DllImprot方式来加载c++DLL.如下格式: //对应c++方法 //voi ...

  2. 在.net中调用Delphi dll的Pchar转换

    Pchar是非托管代码,要在.net中调用Delphi dll中的功能,请使用MarshalAs属性告知.net调用PInvoke去转换.net中标准的string类型.如果Delphi dll是De ...

  3. Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()

    Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...

  4. C#调用C++ DLL类方法

    C++的优势在于高效灵活,C#的优势在于简单易用,两者结合起来对项目开发来说是件好事,而且C++不容易反编译,也保障了代码的安全性,如果一些核心算法使用C#编写,那么保密就是一个问题. C++生成的D ...

  5. paip.java 调用c++ dll so总结

    paip.java 调用c++ dll so总结 ///////JNA (这个ms sun 的) 我目前正做着一个相关的项目,说白了JNA就是JNI的替代品,以前用JNI需要编译一层中间库,现在JNA ...

  6. C#调用C++ DLL 文件

    说来惭愧,都注册一年多了,却没有发表过一篇正式的博文,中间很多学习的过程也没有记录下来.如今到了一个新的环境,也有了学习的机会,一定要把每天的收获记录一下. 要做的东西需要引用C++编写的DLL,刚开 ...

  7. LR调用动态链接库DLL

    什么是动态库? 动态库一般又叫动态链接库(DLL),是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序同时使用的代码和数据的库. 动态链接提供了一种方法 ,使进程可以 ...

  8. C#调用C++ Dll

    现在项目基本都是旁边C++的哥们做好dll扔给我,然后我调用.好久之前晚上down了一份c#调用c++dll的方法,出处早已经遗忘.闲来无事,放上来好了.原作者看到后可以留言,我会把您链接放上的,帮了 ...

  9. 【JNI】OPUS压缩与解压的JNI调用(.DLL版本)

    OPUS压缩与解压的JNI调用(.DLL版本) 一.写在开头: 理论上讲,这是我在博客园的第一篇原创的博客,之前也一直想找个地方写点东西,把最近做的一些东西归纳总结下,但是一般工程做完了一高兴就把东西 ...

  10. c#调用c++ dll的几种类型(转)

    http://www.sosuo8.com/article-2012/dllleixingzhuanhuan.htm   在合作开发时,C#时常需要调用C++DLL,当传递参数时时常遇到问题,尤其是传 ...

随机推荐

  1. nmon的安装使用

    一.下载Nmon 根据CPU的类型选择下载相应的版本: http://nmon.sourceforge.net/pmwiki.php?n=Site.Download http://sourceforg ...

  2. L360 Most People Spend Their Time in Just 25 Places

    Some people are always out on the town, going to concerts, restaurant openings, you name it. They're ...

  3. Prime ring problem,递归,广搜,回溯法枚举,很好的题

    题目描述: A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each ...

  4. 设置Delphi默认按utf8格式保存单元文件

    Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\Software\Embarcadero\BDS\19.0\Editor] " ...

  5. SQL Server DDL

    1:向表中添加字段 Alter table [表名] add [列名] 类型 2:  删除字段 Alter table [表名]  drop column [列名] 3:  修改表中字段类型 (可以修 ...

  6. 关于SpringMVC的配置流程以及一些细节

    首先说道SpringMvc是什么,SpringMVC是Spring框架里面的一个子框架,它对网站前后端的代码分层做了一套实现,这套实现给我们带来了几个好处,首先第一,SpringMVC实现了一个请求对 ...

  7. java.io.IOException: 你的主机中的软件中止了一个已建立的连接。

    1.异常表现:我在jsp文件中有一个<form>表单,里面有一个<button>保存事件按钮.<button  onclick="addOrUPdate()&q ...

  8. python--基本数据 类型

    数据就是我们变量的值:python中变量保存的是内存地址 变量必须先赋值或者声明才能使用!! 1.数值型 整型 int (python3中int就是长整型,与python2中int不同,另外,pyth ...

  9. 一些面试题(关于string的)

    一些常见的面试题: String a = "hello2"; String b = "hello" + 2; System.out.println(a == b ...

  10. exp迁移测试库10.2.0.5

    目的: 将一套10.2.0.5的UP-UNIX系统的数据,迁移到一台Windows环境下. 迁移方案:由于不同的操作系统,为了方便迁移,只是测试,使用EXP/IMP方式. 迁移流程: 一.源端导出 1 ...