小弟在网上找了一片文章,做过一个例子,也出现了奇怪的问题,这里贴出来,大家帮忙看看怎么回事?
文章地址: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模块的错误
这究竟是为什么?  感谢各位大侠解答,谢谢!!!

解决方案 »

  1.   

    大家看不见图吗?我把图片传到网易相册了,但我这里能看见,这样我把错误内容敲出来吧错误是:检测到PInvokeStackImbalance
           对 PInvoke函数“LinkCdll!LinkCDll.Form1::hello“的调用导致堆栈不对称。原因可能是托管的PInvoke签名与非托管的目标签名不匹配。请检查PInvoke签名的调用约定和参数与非托管的目标签名是否匹配。
      

  2.   

    To qthai :
         不是internal的原因,我去掉也一样
      

  3.   

    不知道你用的什么环境编译的,你的代码我用VC6编译DLL,VS 2003调用,没问题,不出错的。
    DLL你可能是2005编译的吧,可能差异在这里,你不要编译托管的DLL试试看。
      

  4.   

    To ezsea :
        你编译的是我的那一楼的代码?顶楼的还是3楼的?
        我确实是在2005中试验的,2005编译dll,2005调用,
        但是我编译dll时创建的是win32的dll,并且编译选项是无clr支持的,应该是非托管的
      

  5.   

    我觉得应该在C++的Dll头文件中加上
    extern "C" _declspec(dllexport)int _stdcall hello(); 这样的说明。
    至于C#程序运行后却出现找不到Count.dll模块的错误,这可能是引用的路径不对,改成[DllImport("C:\\test\Count.dll")]这样的绝对路径试试。
      

  6.   

    To dk385 :
        你说的这种方法我试过,这个实际上和添加一个.def文件2种做法是取其一的,并且我试过错误情况一样。
         另外改为绝对路径后确实不是找不到模块了,但是却出现加载模块的错误,不知你是否可以在你机器上试一下,如果没问题的话,那真是我的环境有问题了?To ezsea :
        我没有装VC6,如果真的跟环境有关系的话那还真是有意思了,呵呵谢谢大家的关注,希望继续讨论!!
      

  7.   

    对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, 栈的清除工作是由调用者来完成的。