c#怎样调用封装的动态链接库cjs函数封装与调用里面的变量

1467人阅读
其他技术方向(25)
& & 最近编写C#程序调用C++语言的算法库,自己尝试在C++中封装好DLL库,并在一个工程文件中同时导出多个函数供C#调用。多个函数之间需要相互通信,但又不能互相调用,,一个很好的方法就是用全局变量来实现,其问题是,C#启动后加载DLL文件,在调用某个函数后修改的DLL中的全局变量值是否会被保存,以供下一个函数调用时共享使用。
& & 经过实验发现,当C#启动后开始加载DLL文件,文件中的初始代码就会执行,所有全局变量会一直保存实值,直到C#程序运行结束或主动释放加载的DLL文件,这样DLL文件就可以被看作一个伴随C#主进程一直运行的子线程,运行过程中不会释放变量。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:76937次
积分:2840
积分:2840
排名:第9979名
原创:54篇
评论:32条
(1)(1)(1)(1)(2)(2)(1)(3)(4)(1)(1)(1)(1)(1)(2)(1)(2)(1)(2)(2)(7)(4)(1)(2)(5)(10)C#调用C++动态链接库函数,有指针怎么调用?-.NET技术/C#-c/c++-电脑编程网C#调用C++动态链接库函数,有指针怎么调用?-.NET技术/C#作者:yuimison 和相关&&C#的winform程序。调用C++动态链接库,函数是 int GetInfo(char *c)C#这边该怎么声明?还有一个函数 int GetInfo(CREC *aRec) CREC是一个结构体。那C#这边 又该如何调用??------回答---------------其他回答(1分)---------int GetInfo(char ref c)& C#定义个CREC是一个结构体。& int GetInfo(CREC ref aRec)------其他回答(1分)---------指针可以考虑使用ref关键字------其他回答(1分)---------int GetInfo(char *c)& 可以试试int GetInfo(stringbuilder c) ------其他回答(1分)---------引用 4 楼 yuimison 的回复:C#声明了这样一个调用dll的函数public int GetInfo(MyRec aRec, ref int iNo);               在调用的时候给arec记录成员赋值;GCHandle gchandle = GCHandle.Alloc(arec); //这个gchandle干什么用的呀??IntPtr lParam = GCHandle.ToIntPtr(gchandle);GetInfo(arec, ref iNo); //调用该函数             gchandle .Free();GCHandle.Alloc(arec); 为指定的对象分配句柄。 ------其他回答(16分)---------ref 就可以了相关资料:|||||||C#调用C++动态链接库函数,有指针怎么调用?-.NET技术/C#来源网络,如有侵权请告知,即处理!编程Tags:                &                    C#调用C/C++动态链接库(.dll)详解——第一篇 编译C的动态连接库
我的图书馆
C#调用C/C++动态链接库(.dll)详解——第一篇 编译C的动态连接库
&在实际工作中,我们经常会将C语言中的.lib和.h文件(静态库)编译成动态连接库.dll文件(这里只提供这两种文件,没有完整的工程),以提供给其他语言平台调用。1,必须有.lib文件,只有.h文件是无法编译动态连接库的。2,我使用的是VS2008,这里打开VS,新建项目—〉win32控制台应用程序,输入项目名称,点击确定,图示如fig.1所示。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&Fig.13,点击下一步,依次如图fig.2-3所示,最后点击完成,就会生成一个带有.cpp的文件。&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&4,打开项目—属性—配置属性—链接器—输入,如下图fig.4所示,在附加依赖项中加入你要添加的.lib文件,如果有一些系统.lib库没有添加或出现错误,可以在忽略特定库中添加该库。注意:如果编译的dll文件调用中出现“xx.dll中找不到函数xx的入口点”,很有可能是一个xx.def文件没有添加,该文件的内容是EXPORTS&&函数名@+序号,将xx.def这个名字填写到下图界面的“模块定义文件”,格式为“./xx.def”。如果这个文件中没有你要调用的API&函数,那么你在C#中是调用不到这个函数的,同时这个文件你可以通过记事本自己编辑,注意!!!&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&5,在.cpp文件中添加.h文件的引用,不需要把所有的.h文件都引用进去,只需要.lib文件入口相关的.h文件。6,最后把.lib和.h文件拷贝到工程debug目录里,生成解决方案就Ok了,你会发现.dll在debug目录中出现。7,最后附上xx.def的格式说明EXPORTS&&&&&&&Fuc1&&&&&&&@&&&&1&&&&&&&Fuc2&&&&&&&@&&&&2&&&&&&&Fuc3&&&&&&&@&&&&3&&&&。。。。。。。省略了呵呵&&&&&&第二篇C#调用C/C++的动态连接库1,清楚C++与C#类型对应关系,即调用关系:&&&&&&&&&&&&&&&&&&&&&除此之外,c++:HANDLE(void *) ---- c#:System.IntPtrc++:WORD(unsigned short) ---- c#:System.UInt16c++:DWORD(unsigned long) ---- c#:System.UInt32c++:结构体&---- c#:public struct&结构体{};c++:结构体&&变量名&---- c#:ref&结构体 变量名c++:结构体&**变量名&---- c#:outc++:GUID ---- c#:Guidc++:UINT8 * ---- c#:ref bytec++:char*/void*(指向一个字符串) ---- c#:string对于结构体中的指针数组,对应于C#中的IntPtr[]类型,如:&&&int * a[] -------------- IntPtr[]a2,清楚在C#中调用C/C++.dll文件的一般格式using System.Runtime.InteropS //必须引用的命名空间[DllImport("user32.dll")]public static extern ReturnType FunctionName(type arg1,type arg2,...);//必须定义为类的静态外部的方法3,[DllImport(参数)]设定①“xx.dll”&:dll文件名字②CharSet&:控制调用函数的名称版本及指示如何向方法封送&String&参数。如果&CharSet字段设置为&Unicode,则所有字符串参数在传递到非托管实现之前都转换成&Unicode&字符。这还导致向&DLL EntryPoint&的名称中追加字母“W”。如果此字段设置为&Ansi,则字符串将转换成ANSI&字符串,同时向&DLL EntryPoint&的名称中追加字母“A”。EntryPoint&指示要调用的&DLL&入口点的名称或序号。如果你想使用自己定义的函数名字fucXX,则:”EntryPoint=fucXX”。③ExactSpelling:指示是否应修改非托管&DLL&中的入口点的名称,以与&CharSet&字段中指定的&CharSet&值相对应。如果为&true,则当&DllImportAttribute.CharSet&字段设置为CharSet&的&Ansi&值时,向方法名称中追加字母&A,当&DllImportAttribute.CharSet&字段设置为&CharSet&的&Unicode&值时,向方法的名称中追加字母&W。此字段的默认值是&false。④PreserveSig:指示托管方法签名不应转换成返回&HRESULT、并且可能有一个对应于返回值的附加&[out, retval]&参数的非托管签名。⑤SetLastError:指示被调用方在从属性化方法返回之前将调用&Win32 API SetLastError。true&指示调用方将调用&SetLastError,默认为&false。4,具体实例C中API函数:Unsigned long int Fuc (int a,void* b);C#中定义:[DllImport("testall.dll", ExactSpelling =&false)]public&extern&static&UInt32&Fuc(int&a, IntPtr&b);//C中结构体:#define M 5typedef struct __BITMAP{DWord pPixelArrayFLong lWLong lHLong lBuffer [MPAF_MAX_PLANES];Byte* pPointer[MPAF_MAX_PLANES];}BITMAPC#定义:&&&&&&&[StructLayout(LayoutKind.Sequential)] //此句在C#中重新定义结构体时一定要加上&&&&&&&&public&struct&BITMAP&&&&&&&&{&&&&&&&&&&&&[MarshalAs(UnmanagedType.U4)]&&&&&&&&&&&&public&UInt32&pPixelArrayF&&&&&&&&&&&&[MarshalAs(UnmanagedType.I4)]&&&&&&&&&&&&public&Int32&lW&&&&&&&&&&&&[MarshalAs(UnmanagedType.I4)]&&&&&&&&&&&&public&Int32&lH&&&&&&&&&&&&[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]&&&&&&&&&&&&public&Int32[] lB&&&&&&&&&&&&&[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]&&&&&&&&&&&&public&IntPtr[] pP&&&//对于结构体中的指针数组,一般采用IntPtr数组&&&&&&&&}对于上面的这个结构体,如果在C/C++中出现了结构体指针,那么我们应该在C#中使用IntPtr类型变量,然后使用如下方法将指针指向结构体。定义结构体对象S,则在C#中获取结构体指针的方法如下:IntPtr intptr = Marshal.AllocHGlobal(Marshal.SizeOf(S));&Marshal.StructureToPtr(S, intptr, false); //将指针intptr指向结构体操作之后一定要释放内存——Marshal.FreeHGlobal(intptr);//释放分配的非托管内存。反之也可以由指向结构体的指针变量获取结构体。Marshal.PtrToStructure();
发表评论:
TA的最新馆藏[转]&

我要回帖

更多关于 jq函数封装与调用方法 的文章

 

随机推荐