问题1:我在VC里面做了一个DLL,DLL里面就一个函数MsgBox(),返回值是INT类型,它的功能就是弹出一个MESSAGEBOX对话框,当然是调用的VC里面的MessageBox()函数,这个函数有三个参数分别是VC中的 LPCTSTR,LPCTSTR和UINT类型的,我现在已经在VC下编译通过并生成了一个.DLL文件,我想在VB里调用它,一按一个按钮让它实现弹出一个MESSAGEBOX,我该如何去做,这三个叁数的类型在VB里怎么转换,是不是除了DLL文件还需要其他文件,我是不是要把DLL文件COPY到VB的这个项目的目录下呢?问题2:我用VC编的程序可以很好的调用该DLL,但是采用动态加载的时候,当弹出对话框后告诉我DEBUG ERROR,说The value of ESP was net properly saved across a function call.this is usually a result of calling a function declared with one calling convention with a function pointer delclared with a different calling convertion
这是什么原因?"ESP"在我的程序里根本没有.用静态加载没有问题.
我的调用DLL的程序是一个WIN32 Application工程,里面就一个CPP.
请问各位高手这是怎么回事.
第二个问题的CPP全部代码如下:
#include <windows.h>typedef int (CALLBACK* DLLFUNC)
 (
 LPCTSTR lpText="it is a simple,but it is good!",
 LPCTSTR lpCation="a simple",
 UINT=MB_OK);int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
 HINSTANCE hDLL;
 DLLFUNC MsgBox;
 hDLL=LoadLibrary("dllexe");  if(hDLL!=NULL)
 {
 MsgBox=(DLLFUNC)GetProcAddress(hDLL,"MsgBox");
 return MsgBox();
 }
 //return 0;
}

解决方案 »

  1.   


    问题2:
    typedef int (CALLBACK* DLLFUNC)
     (
     LPCTSTR lpText="it is a simple,but it is good!",
     LPCTSTR lpCation="a simple",
     UINT=MB_OK);
    改为
    typedef int (CALLBACK* DLLFUNC)
     (
     LPCTSTR lpText,
     LPCTSTR lpCation,
     UINT=MB_OK);
      

  2.   

    LPCTSTR  vb导出后对应 string 
    UINT     vb到处后对应 long
      

  3.   

    to  danmao(愤怒的小mao) :你让我那么做,我都没给参数赋值了,我还调用DLL干嘛啊,而且照你那么改编译都通不过,会报出"没有实际参数"错误(不奇怪),还有能解决的吗???
      

  4.   

    问题2:
    应该是你的参数的个数不对原因,你把要填写的参数全部填写一遍就可以了
    MsgBox ( LPCTSTR lpText="it is a simple,but it is good!",
     LPCTSTR lpCation="a simple",
     UINT=MB_OK);ESP是汇编里的一个寄存器,你转到那里就看到了
      

  5.   

    MsgBox ("it is a simple,but it is good!",
     "a simple",
     MB_OK);
      

  6.   

    为了你这个问题,搞了我一上午,应该多给我分。
    问题1:
    Public Declare Function mm Lib "dllexe.dll" Alias "_MsgBox@12" (ByVal m As String, ByVal t As String, ByVal op As Long) As LongSub a()
    Dim l As Long
     l = mm("asdlkfja", "da", 0)
    End Sub问题2:错在DLL源程序,修改你的源程序
    extern "C"
    {
      DLLEXE_API WINAPI MsgBox(char * msg, char * title, UINT op);
    //必须这样申明,不得通融,DLLEXE_API是向导产生的你应该知道
    //但这样声明后输出函数名变成_MsgBox@12,不知道为什么
    //我是用别的工具看见这个名字的
    }DLLEXE_API WINAPI MsgBox(char * msg, char * title, UINT op)
    {
     return MessageBox(0,msg,title,op);
    }你的调用程序也有错,正确程序如下:
    #include <windows.h>typedef int (CALLBACK* DLLFUNC) (LPCTSTR lpText, LPCTSTR lpCation, UINT O);int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    {
     HINSTANCE hDLL;
     DLLFUNC MsgBox;
     hDLL=LoadLibrary("dllexe.dll");
     if(hDLL!=NULL)
     {
     MsgBox=(DLLFUNC)GetProcAddress(hDLL,"_MsgBox@12");
     return MsgBox("it is a simple,but it is good!","a simple", MB_OK);
     }
     return 0;
    }这样就没问题了,我提供的程序是全部运行通过的。
      

  7.   

    GetProcAddress(hDLL,"_MsgBox@12")中的_MsgBox@12是什么,为什么这么写???
      

  8.   

    to : icansaymyabc(学习与进步) 
    extern "C" __declspec(dllexport) MsgBox(char * msg, char * title, UINT op);
      

  9.   

    extern "C" __declspec(dllexport) MsgBox(char * msg, char * title, UINT op);
    不行的,这样编译后还是有名字分裂。可以把__declspec(dllexport)去掉,然后在def文件的exports中加上MsgBox一行。好象跟msdn里说的不大一样,但事实是这样。
      

  10.   

    to  cxiaobao(风子) :不会吧,我的怎么就没事呢,当然你说的也是一种方法了
      

  11.   

    我现在用的是动态加载啊,没有.DEF文件啊,没有这个在VB里能调用吗?
    PS:我的DLL是WIN32的,不是MFC.
      

  12.   

    我想问GetProcAddress(hDLL,"_MsgBox@12")中的_MsgBox@12是什么,为什么这么写???
      

  13.   

    问题很多
    1。extern "C" __declspec(dllexport) _stdcall int MsgBox(char * msg,
                                        ~~~~~~~~~~~~
     char * title, UINT op);2.Public Declare Function mm Lib "dllexe.dll" Alias "MsgBox" (ByRef
                                                                 ~~~~~  
     m As String, ByRef t As String, ByVal op As Long) As Long
                 ~~~~~~  
    3。typedef int (*DLLFUNC) (LPCTSTR lpText, LPCTSTR lpCation, UINT
                    ~~~~~ 
     O);4。不用在函数后面加 @xxx
      

  14.   

    我也不知道他为什么把MsgBox变成_MsgBox@12,
    我只知道这样做就不出错了。
    应该把比尔盖抓来审,才能知道原因
      

  15.   

    siphonelee(sifone) 你都有星了,干吗还提这么多问题,你应该是解决问题的才对。
      

  16.   

    呵呵,看样子是你的概念还不太清楚。
    函数的默认参数应该在函数定义的地方添加。而
    typedef int (CALLBACK* DLLFUNC)
     (
     LPCTSTR lpText,
     LPCTSTR lpCation,
     UINT=MB_OK);
    定义的只是接口!这里定义只是一个指向函数的指针,这个函数是一个返回值为int的回调函数。参数是……然后你定义一个函数接口同上,不过需要给出默认参数(就是你开始定义的那些)。你调试一下吧。我没有调试。因为你并不是在外部调用这个函数,所以楼上说的添加
    extern "C" __declspec(dllexport)
    没有必要。以上基于你的cpp,头文件你应该会吧 :)
      

  17.   

    to icansaymyabc(学习与进步) MsgBox@12是它真正的名字
    用depend 可以看到
      

  18.   

    呵呵,不好意思,没有看清楚你的问题。
    没有办法,现写一个了。
    假设你的动态链接库正确,外部接口函数定义为
    int CALLBACK MyMessageBox(
     LPCTSTR lpText,
     LPCTSTR lpCation,
     UINT uType);你的cpp如下:
    #include <windows.h>typedef int (CALLBACK* DLLFUNC)(
     LPCTSTR lpText,
     LPCTSTR lpCation,
     UINT );int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    {
     HINSTANCE hDLL;
     DLLFUNC pMsgBox;
     hDLL=LoadLibrary("dllexe.dll");  if(hDLL!=NULL)
     {
     pMsgBox=(DLLFUNC)GetProcAddress(hDLL,"MyMessageBox");
     if (NULL != pMsgBox)
                             pMsgBox("it is a simple,but it is good!","a simple",MB_OK);
     }
              FreeLibrary(hDLL);
     return 0;
    }这样应该没有问题。
    首先要保证你的dll没有问题!!!
      

  19.   

    icansaymyabc(学习与进步) 说的没错,我也碰到了这个问题,GetProcAddress()里的函数名可能不能使用DLL里的函数名,需要在函数名前面加上“—”,函数名后加上“@(还有一个数字)"就可以了。。DLL里输出的真正的函数名可能和DLL里的函数名不一致,输出的真正的函数名可以通过命令行工具DUMPBIN来查看我也问过类似的问题,谢谢icansaymyabc(学习与进步) 给我的解答但我也不明白,我看过的所有范例程序在GetProcAddress()里都是直接使用DLL里的函数名的,从来没见过使用修饰名的。。在什么情况下要使用修饰名呢???不明白
      

  20.   

    雖然我沒學過VC
    但如有前輩願意提供此題的範例程式 (我想用dll 来传参数)
    我可能可以藉此作中學
    所以
    煩請
    高手為我指點 , 寫一下這題範例
    小妹會感激不盡…..謝謝~~~~~~~~~~~~~~~
      

  21.   

    我看是多了一个FreeLibrary(hDLL),我的机器重做了等我装上VS后再试一下
      

  22.   

    我的DLL应该是没问题,因为我用静态连接时DLL工作的好好的,danmao(愤怒的小mao) 我把你的源代码COPY过去了结果一样!!!!