当前位置:编程学习 > C#/ASP.NET >>

C#调用C++的DLL问题,非常严重,小弟拜谢求解!!!

-------C++的dll代码---------
********trydll.cpp****************
// trydll.cpp : 定义 DLL 应用程序的入口点。
//

#include "stdafx.h"
#include "trydll.h"
//BOOL APIENTRY DllMain( HANDLE hModule, 
//                       DWORD  ul_reason_for_call, 
//                       LPVOID lpReserved
//  )
//{
//    return TRUE;
//}
bool APIENTRY abc::hello()
{
MessageBox(NULL,"aaa","third",MB_OK);
return true;
}


**************trydll.h***************
class abc
{

public:

bool APIENTRY hello();

};


*************trydll.def*************
LIBRARY	"trydll"

EXPORTS
    hello;


---------------C#代码--------------

        [DllImport("trydll.dll")]
        internal static extern bool hello();

        private void Form1_Load(object sender, EventArgs e)
        {

            hello();
        }


运行后首先弹出"aaa"的MessageBox 接着 hello(); 这一行就出现这样的一个错误窗口:

请问这是什么原因造成的?
C#调用C++的DLL,使用哪种方法最好?最好能具体说明,万分感激,小弟拜谢了!!!! --------------------编程问答-------------------- 难道是因为internal? --------------------编程问答-------------------- 此图片仅限于网易用户交流沟通使用!
难道是你和网易的版权问题? --------------------编程问答-------------------- 小弟在网上找了一片文章,做过一个例子,也出现了奇怪的问题,这里贴出来,大家帮忙看看怎么回事?
文章地址:http://blog.csdn.net/Steven_god/archive/2007/12/13/1932798.aspx

----------------C++代码------------------------

// Cdll.cpp : 定义 DLL 应用程序的入口点。
//

#include "stdafx.h"


#ifdef _MANAGED
#pragma managed(push, off)
#endif

// 导出函数,使用“ _stdcall ” 标准调用 
extern "C" _declspec(dllexport)int _stdcall count(int init); 

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
 )
{
    return TRUE;
}

int _stdcall count(int init) 

{//count 函数,使用参数 init 初始化静态的整形变量 S ,并使 S 自加 1 后返回该值 

static int S=init; 

S++; 

return S; 




#ifdef _MANAGED
#pragma managed(pop)
#endif



----------------------C#代码------------------

        [DllImport("Count.dll")]
        static extern int count(int init);
        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(" 用 DllImport 调用 DLL 中的 count 函数, \n 传入的实参为 0 ,得到的结果是: " + count(0).ToString(), " 挑战杯 ");
            .....
        }


将dll生成的Count.dll复制到了C#工程的/bin/Debug/文件夹下,两边编译都没问题,运行后却出现找不到Count.dll模块的错误
这究竟是为什么?  感谢各位大侠解答,谢谢!!! --------------------编程问答-------------------- 大家看不见图吗?我把图片传到网易相册了,但我这里能看见,这样我把错误内容敲出来吧

错误是:检测到PInvokeStackImbalance
       对 PInvoke函数“LinkCdll!LinkCDll.Form1::hello“的调用导致堆栈不对称。原因可能是托管的PInvoke签名与非托管的目标签名不匹配。请检查PInvoke签名的调用约定和参数与非托管的目标签名是否匹配。 --------------------编程问答-------------------- To qthai :
     不是internal的原因,我去掉也一样 --------------------编程问答-------------------- 关注中,顶~!!!!!!!!! --------------------编程问答-------------------- 顶一下 --------------------编程问答-------------------- 顶起来,希望能得到更多高手的关注!!! --------------------编程问答-------------------- 不知道你用的什么环境编译的,你的代码我用VC6编译DLL,VS 2003调用,没问题,不出错的。
DLL你可能是2005编译的吧,可能差异在这里,你不要编译托管的DLL试试看。 --------------------编程问答-------------------- To ezsea :
    你编译的是我的那一楼的代码?顶楼的还是3楼的?
    我确实是在2005中试验的,2005编译dll,2005调用,
    但是我编译dll时创建的是win32的dll,并且编译选项是无clr支持的,应该是非托管的 --------------------编程问答-------------------- 我觉得应该在C++的Dll头文件中加上
extern "C" _declspec(dllexport)int _stdcall hello(); 这样的说明。
至于C#程序运行后却出现找不到Count.dll模块的错误,这可能是引用的路径不对,改成[DllImport("C:\\test\Count.dll")]这样的绝对路径试试。
--------------------编程问答-------------------- 我编译的是你3楼的,呵呵,我是没编出问题啦 --------------------编程问答-------------------- To dk385 :
    你说的这种方法我试过,这个实际上和添加一个.def文件2种做法是取其一的,并且我试过错误情况一样。
     另外改为绝对路径后确实不是找不到模块了,但是却出现加载模块的错误,不知你是否可以在你机器上试一下,如果没问题的话,那真是我的环境有问题了?

To ezsea :
    我没有装VC6,如果真的跟环境有关系的话那还真是有意思了,呵呵

谢谢大家的关注,希望继续讨论!! --------------------编程问答-------------------- 对PInvoke函数“LinkCdll!LinkCDll.Form1::hello“的调用导致堆栈不对称。原因可能是托管的PInvoke签名与非托管的目标签名不匹配。请检查PInvoke签名的调用约定和参数与非托管的目标签名是否匹配。
从这里来看,如果排除了C#参数与DLL的参数不一致的情况,可能就是调用约定不一致或字符集不一致。
可以这样试下:
[DllImport("C:\\test\\Count.dll",   CharSet=CharSet.Auto,   CallingConvention=CallingConvention.StdCall)] 
[DllImport("C:\\test\\Count.dll",   CharSet=CharSet.Ansi,   CallingConvention=CallingConvention.Cdecl)] 
1. 用__stdcall,栈的清除工作是由函数自己解决清除工作,
2  用 _cdecl, 栈的清除工作是由调用者来完成的。
--------------------编程问答-------------------- dll不要输出类函数
--------------------编程问答-------------------- 顶起,希望得到更多高手的解答,谢谢!!
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,