C++ 帮我c 将dll编译进exe一下这个dll

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的最新馆藏[转]&今天反编译一个DLL时,看到一个奇怪的入口,请问一下应该怎么理解 - C++当前位置:& &&&今天反编译一个DLL时,看到一个奇怪的入口,请问一今天反编译一个DLL时,看到一个奇怪的入口,请问一下应该怎么理解&&网友分享于:&&浏览:0次今天反编译一个DLL时,看到一个奇怪的入口,请教一下应该如何理解?private:&static&class&UClass&AKConstraint::PrivateStaticClass
如题。我现在能理解的部分:
1.private&,成员变量是private的。
2.static,静态成员
3.UClass&是一个类
不能理解的部分:AKConstraint::PrivateStaticClass
请问,这应该如何理解?------解决方案--------------------没有typedef这类东西,这么复杂的东西,不会就这么拿出来用吧
12345678910
12345678910
12345678910 上一篇:下一篇:文章评论相关解决方案 12345678910 Copyright & &&版权所有我用VS2005编译了一个C++的DLL,类型是“带静态链接MFC的规则DLL”,现在想看看外部传进来的字符串参数是否正确,该用什么语句呢?
DLL中的导出函数:
extern&&C&&__declspec(&dllexport&)&void&Dcm2Bmp(char&*pFileName)
AFX_MANAGE_STATE(AfxGetStaticModuleState());
&&&&AfxMessageBox(pFileName);
CDcmBmp&m_DcmB
strcpy(m_DcmBmp.m_strFileName,&buf);
m_DcmBmp.ConvertDicomToBMP();
如上所示,我试着用AfxMessageBox(pFileName);查看传进来的字符串是否正确,但项目调用时,根本弹不出显示pFileName所指字符串的对话框,编译可以通过,但运行时出一个错误提示,还没看清,程序就自动终止了,就啥也没有了,怎么回事呢?但在另一个地方有段代码:
fp&=&fopen(pszFileName,&&rb&);
&&&if&(!fp)
&&&&&&&AfxMessageBox(_T(&Failed&to&open&file&for&read.&));
这段代码就可以输出字符串&Failed&to&open&file&for&read.&,也正是因为老是打不开文件,所以我想看看传进来的路径字符串到底是什么(因为我怀疑传进来的字符串不对),因为若把上面的程序改成:
fp&=&fopen(“&\\My&Documents\\ct1.dcm&”,&&rb&);
&&&if&(!fp)
&&&&&&&AfxMessageBox(_T(&Failed&to&open&file&for&read.&));
就可以打开文件,一切都顺利,但就是从外部传进来相同的路径字符串,就是打不开,老跳出对话框“Failed&to&open&file&for&read.”,所以我想看看传进来的路径字符串到底变成了什么,用开头我说的那个AfxMessageBox(pFileName);不行?那我要怎么办呢?望大家不吝赐教,谢谢啦!!!!!
回复讨论(解决方案)
楼主应该会调试吧,在调试的时候监视这个变量就可以看到是不是那个字符串了
直接设置断点跟踪就可以看到了,为什么一定要用AfxMessageBox呢。
我是在我的C#项目里调用这个C++DLL,只是把做好的DLL文件放到项目的同一目录下,要设断点只能在DLL里面设,DLL是封装的根本看不到代码,没法设呀。再说监视变量难道能跟踪到DLL中去?困惑,我是新手,请各位大侠指教!!
你自己用C++先写个程序,测试一下是不是这个DLL的问题
如果不是的话,那就应该是C#代码的问题了
最不喜欢工程和DLL的联调
让人很郁闷
DLL你不是有源代码么,那就能调试啊
&&谢谢各位大哥的热心解答!
&&C#的代码应该没有问题的,就是DLL的问题,我有DLL的代码,但不会在项目中调试。
&&今天有个网友告诉我一个方法:先把DLL项目(名字叫wwstest2)添加到解决方案里,然后右击“引用”选择“添加引用”,然后选择“项目”下面的我的DLL项目,确定就可以了,这时“引用”下面就多了我那个dll,然后就可以在我的C#的引用处和DLL里面分别设置断点进行调试了。但我选择“项目”下面的我的DLL项目,点确定之后,就提示对话框:未能添加对“wwstest2”的引用。
&&怎么回事呢?大家能帮帮小弟吗?感激不尽呀!!!!!
把c&sharp和dll两个工程放在一个解决方案里面就可以调试了。
更进一步,你可以在依赖关系中,加入c&sharp工程依赖dll工程。
好像不用添加引用吧。我调试想来都是放在一个工程里面调。
我按楼上的大哥的方法试了,把两个工程放在了同一解决方案里,并使我的C#项目依赖于我的dll工程,但设置断点还是跟踪不到dll里面呀,唉,愁死了,哪位大哥还有好方法吗?帮帮小弟吧。。。。
不应该呀。
全盘搜索一下这个dll,把除当前工程编译出来的dll以外的其它dll副本都删掉。
会不会你的c&sharp程序调用了另外一个dll呀。
还是不行呀,C#里就调用了这一个DLL呀,真奇怪了,唉。还有大哥能给点提示吗?快疯了。。。。
我的意思是,比如这个dll叫a.dll,是不是还有其它叫a.dll的文件?
还有其它更笨的调试方法,比如直接把这个pFileName的内容写入到一个文件里,然后看文件内容是否正确。
调试的方法有很多,你可以自己想。没必要非要在IDE里面直接看。
&&我全盘搜索了,没有和我的dll重名的呀。
&&把pFileName这个路径字符串写到文件里?要怎么写呢?不好意思我是个菜鸟,汗~~~~
&&我帖子开头就是想把这个路径字符串的内容用对话框显示出来,但不知怎么老是不行,他们提示我设断点调试我才考虑设断点的,唉,断点也调不成,快疯了
把调用这个dll的可执行程序放在你的dll的debug目录内。
然后直接打开dll工程,设断点,debug编译,运行。
这个时候会提示你选哪个程序运行,然后你选那个可执行程序。
应该可以调试了。
如果还不行,你还是找身边的人看看吧。
我按楼上大哥的说法试了&,但并没有出现您说的提示我选哪个程序运行呀,唉,怎么回事呢?
还有哪位大哥有工程和DLL联调的经验吗?可否给小弟点指点?
救命呀..........
将dll项目设为启动项目再运行
不行呀,呜呜
在你DLL那个工程里 
Project->setting->Debug中
Executable for debug session:
右边的箭头,把工程连接到C#那个工程中调用的那个DLL
调试就ok了
extern&&&&C&&&&__declspec(&&&dllexport&&&)&&&void&&&Dcm2Bmp(char&&&*pFileName)&
AFX_MANAGE_STATE(AfxGetStaticModuleState());&
CString&szS
szStr&=&pFileN
AfxMessageBox(szStr);
CDcmBmp&&&m_DcmB&
strcpy(m_DcmBmp.m_strFileName,&&&buf);&
m_DcmBmp.ConvertDicomToBMP();&
extern&&&&C&&&&__declspec(&&&dllexport&&&)&&&void&&&Dcm2Bmp(char&&&*pFileName)&
AFX_MANAGE_STATE(AfxGetStaticModuleState());&
&&&&CString&szS
&&&&szStr&=&pFileN
&&&&AfxMessageBox(szStr);
CDcmBmp&&&m_DcmB&
strcpy(m_DcmBmp.m_strFileName,&&&buf);&
m_DcmBmp.ConvertDicomToBMP();&查看: 1120|回复: 2
会C++的来一下,帮忙编译生成一个DLL文件,谢谢
阅读权限10
会C++的来一下,帮忙编译生成一个DLL文件,谢谢。
代码:/s/1gdrID7X
源文件是C#,大致是一个解密XML文件的算法,都是核心语言,没有什么复杂的,就一些位运算,希望能帮忙编译一个DLL(因为我要其它程序调用,关键是C#编译的DLL无法给其他程序调用。。
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限10
菜鸟帮顶,不知道这样的主题算不算违规
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
阅读权限20
顶下,坐等大神
发帖求助前要善用【】功能,那里可能会有你要找的答案;如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】和【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
免责声明:吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
( 沪ICP备号 | 京公网安备 87号 )
Powered by Discuz! X3.2
Comsenz Inc.trackbacks-0
&&&& &在写C++程序时,时常需要将一个class写成DLL,供客户端程序调用。这样的DLL可以导出整个class,也可以导出这个class的某个方法。
一、导出整个class
方法很简单,只需要在类的头文件中class和类名之间加上_declspec(dllexport),同时在另外一份提供给客户端调用程序使用的类的头文件中class和类名之间加上_declspec(dllimport)。为了能让客户端程序和DLL程序公用该类的一份头文件,通常在类的头文件中使用宏和预编译指令来处理。如下DLLTest.h:
DLL_TEST_API
#define DLL_TEST_API _declspec(dllimport)
Class DLL_TEST_API
CDLLTest();
~CDLLTest();
int Add(int a, int b);
&DLLTest.cpp如下:
#define DLL_TEST_API
_declspec(dllexport)
#include &DLLTest.h&
&&&&&&&&&&&&&&&
&这样,在DLL编译时DLL_TEST_API被定义为_declspec(dllexport),而且客户端程序编译时它被定义为_declspec(dllimport)。
二、导出这个类的某个或者某几个方法。
这时,需要将_declspec(dllexport)放到成员函数名前,如DLLTest.h:
#ifdef DLL_TEST_API
#define DLL_TEST_API _declspec(dllimport)
Class CDLLTest
CDLLTest();
~CDLLTest();
DLL_TEST_API
Add(int a, int b);
但是,如果仅仅是这样的话,当客户端程序#include这个头文件后,定义DLLTest这个类的一个对象后(静态方式链接DLL),客户端程序无法链接通过,会提示构造函数和析构函数无法解析,此时,需要将构造函数和析构函数前也加上DLL_TEST_API宏即可。
当然这里还有个问题就是类的函数在导出后,名字会发生变化,我们可以在函数名前再加上extern &C& ,如 extern &C& DLL_TEST_API int Add(int a ,int b);但这只解决了C与C++调用时名字变更问题,可靠的方法还是增加一个模块定义文件def,在该文件中定义导出函数的名称,我们将在后面看到样例。
DLL编写完成后,就只剩下客户端程序如何去调用该DLL了,静态方式调用DLL和动态方式调用DLL。
一、静态方式调用DLL
这个方法就简单了,将DLLTest.h头文件和DLLTest.lib,DLLTest.dll文件拷贝到客户端程序的当前目录下,在客户端程序中#include&DLLTest.h&,然后通过#pragma comment(lib,&DLLTest.lib&)的方式引入lib库,或者在客户端程序的工程属性里面增加对该lib文件的引入。
然后就可以在客户端程序中如同使用本地的一个class一样使用该DLL了,如:
CDLLTest dllT
dllTest.Add(1,2);
二、动态方式调用DLL
动态调用这个DLL,就需要对这个class进行修改了。
首先,在DLLTest.cpp文件中增加一个全局函数,该函数可以返回这个class的一个实例,这样,客户端程序调用这个全局函数后,得到该class的实例,就可以调用该class的实例方法了。
extern &C&
_declspec(dllexport)
GetInstance()
return new CDLLT
&注:extern &C& 只是解决了c与c++编译器之间的兼容问题,如果需要和其他编译器之间兼容,可靠的办法还是增加一个.def文件,文件内容如下:
GetInstance = GetInstance
&这样就指定了DLL的函数导出后的名称仍然不变。
这样,客户端程序就可以通过该函数来获取class的一个实例了。如下:
先需要定义一个函数指针类型:
CDllTestBase*
(*pfGetInst)();
//注:CDllTestBase类后面会介绍。
HMOUDLE hMod = LoadLibrary( _T(&DLLTest.DLL&) );
pfGetInstance
(pfGetInst)GetProcAddress(&GetInstance&);
//通过基类指针指向派生类对象
CDllTestBase * pInst = pfGetInstance ();
if( NULL != pInst )
pInst-&Add( 1,2);
if( NULL != pInst )
//释放对象
&&&&& 当然,这里还是需要include这个DLL的头文件DLLTestBase.h,如果将之前所写的头文件DLLTest.h直接拷贝到客户端程序的当前目录下,并include进来的话,在编译连接时,是无法通过的,我们需要对这个头文件进行修改,首先增加一个.h 文件DLLTestBase.h,在这个文件中我们将需要在客户端程序中调用的函数都命名成纯虚函数,然后让CDLLTest类继承自CDLLTestBase类,DLLTestBase.h如下:
CDLLTestBase
~CDLLTestBase(){};//虚析构函数,且为内联函数
Virtual int Add(int a, int b) = 0;
&DLLTest.h修改后如下:
#include &DLLTestBase.h&
Class CDLLTest
CDLLTestBase
CDLLTest();
~CDLLTest();
Add(int a, int b);
注:这里的DLLTestBase需要提供一个虚析构函数,这样在客户端程序中就可以通过基类指针来释放派生类对象了。
&&&&& 这样,只需要将DLLTestBase.h拷贝到客户端程序的当前目录下,然后在客户端程序中#include&DLLTestBase.h&,就可以如上面介绍一样在客户端程序中调用DLL里面的方法了。
阅读(...) 评论()}

我要回帖

更多关于 c dll 反编译 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信