如何在一个托管的C++工程中,调用一个基于MFC的DLL???急求

托管工程是基于CLR的,我原来在MFC中写过一段基于MFC的功能,现在想直接用其dll,调试过程中总是崩溃,急求?????您好,目前存在一个问题,就是基于MFC的非托管的... 托管工程是基于CLR的,我原来在MFC中写过一段基于MFC的功能,现在想直接用其dll,调试过程中总是崩溃,急求?????
您好,目前存在一个问题,就是基于MFC的非托管的C++代码中,存在大量的Cstring类型变量,但是建立的CLR的windows的窗体应用程序,只存在string类型,这样就会报错:
未处理的“System.Runtime.InteropServices.SEHException”类型的异常出现在 System.Windows.Forms.dll 中。

不知道怎么解决这个问题呢???
展开
 我来答
Subelfin
2011-10-28 · TA获得超过445个赞
知道小有建树答主
回答量:199
采纳率:0%
帮助的人:136万
展开全部
我想,你应该已经在网上查到大概的用法了吧,比如:
[DllImport(“hello.dll”)]
private extern static int DeviceOpen(int aDevType, int aDevIndex, ref IntPtr aHandle);
用于调用hello.dll里的DeviceOpen函数。

但是这个时候可能会出现一些莫名其妙的问题,常见的有如下两个:
1. 函数名。C++编译器对函数名的处理与C不同,会加上一些字符用于标识函数的参数信息,比如上述的DeviceOpen函数的实际名称,可能就是:
?DeviceOpen@@YAHHHPAPAX@Z
这个可以用十六进制编辑器在你的Dll里面查找然后验证一下,一般都是前面后面加上一点字符而已。
然后使用时就这样:
[DllImport(DLL_FILE, EntryPoint = "?DeviceOpen@@YAHHHPAPAX@Z")]
private extern static int DeviceOpen(int aDevType, int aDevIndex, ref IntPtr aHandle);

2. 调用协定。对于CLR来说普通的WindowsAPI,调用协定是默认值,也就是stdcall。但是C++编译出来的函数,默认值一般是cdecl。所以想正确调用自己编写的Dll内的函数,还要指定调用协议。如:
[DllImport(DLL_FILE, CallingConvention = CallingConvention.Cdecl, EntryPoint = "?DeviceOpen@@YAHHHPAPAX@Z")]
private extern static int DeviceOpen(int aDevType, int aDevIndex, ref IntPtr aHandle);

你先试试看?如果还有什么问题,可以再追问,最好把错误信息也贴出来。
追问
非托管C++代码,存在大量Cstring类型变量,但是建立CLR的windows的窗体应用程序,只存在string类型,会报错:未处理“System. Runtime.InteropServices. SEHException” 类型的异常出现在System.Windows.Forms.dll 中。怎么解决?
例如:非托管的DLL中,其中一个函数为: CString Test(CString a, CString b, int c);
在托管中怎么用private extern static String Test( CString aDevType, CString aDevIndex);
追答
SEHException应该是在调用过程中,C++程序抛出了异常未受处理而发生的异常

总的来说,想在C#中直接使用C++类就比较困难了,理论上可以,实际上代价比较高。因为C++类说到底不是一个跨语言的技术。
那么跨语言的技术有什么呢?除了普通的函数/过程调用,就还有COM。
因此你所遇到的这个情况,推荐的做法是如下两个:
1. 用面向过程的方法封装一下非托管代码,用extern "C",__stdcall修饰一下,导出,编译成dll,供托管代码调用。
2. 用COM技术对原有代码进行封装,然后在托管代码中加载该COM组件使用。
何处淬吴钩
2011-10-29 · TA获得超过5044个赞
知道大有可为答主
回答量:2947
采纳率:50%
帮助的人:2397万
展开全部
对于CLR来说普通的WindowsAPI,调用协定是默认值,也就是stdcall。但是C++编译出来的函数,默认值一般是cdecl。所以想正确调用自己编写的Dll内的函数,还要指定调用协议。如:
[DllImport(DLL_FILE, CallingConvention = CallingConvention.Cdecl, EntryPoint = "?DeviceOpen@@YAHHHPAPAX@Z")]
private extern static int DeviceOpen(int aDevType, int aDevIndex, ref IntPtr aHandle);
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
百度网友590cfbf
2011-10-28 · 超过17用户采纳过TA的回答
知道答主
回答量:152
采纳率:0%
帮助的人:47.7万
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
匿名用户
2011-10-29
展开全部
{
typedef int (WINAPI ICEPUB_SENDMAILTEXT)(char *strUsername,char *strPassword,char *strSmtpServer,char *sendMail,char *toMailList,char *strSubject,char *strText);
ICEPUB_SENDMAILTEXT *icePub_sendMailText = 0;
HINSTANCE hDLLDrv = LoadLibrary("icePubDll.dll");
if(hDLLDrv)
{
icePub_sendMailText = (ICEPUB_SENDMAILTEXT *)GetProcAddress(hDLLDrv, "icePub_sendMailText");
}
if(icePub_sendMailText)
icePub_sendMailText("ahuinuli","112233","smtp.tom.com","ahuinuli@tom.com","mike@sina.com","标题:还好么?","文本:扉心祈梦,梦语问春天。");
if(hDLLDrv)
FreeLibrary(hDLLDrv);
}

原型:
int WINAPI icePub_sendMailText(char *strUsername,char *strPassword,char *strSmtpServer,char *sendMail,char *toMailList,char *strSubject,char *strText)
输入:strUsername smtp用户名
strPassword 用户密码
strSmtpServer smtp服务器
sendMail 发件人邮箱地址
toMailList 收件人邮箱地址,多个以分号分隔
strSubject 标题
strText 文本内容
输出:
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(2)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式