我有VC写的一个DLL,用VB调用其中一个函数时出现Bad dll calling convention错误,而且古怪的是当我把VB程序编译成EXE后,运行却没有这个错误。看MSDN的介绍说是参数类型不对或参数个数不对,但我找来找找去也没发现有啥问题,不需要考虑stdCall的问题,因为DLL的所有函数都是一样的,其它的函数都能使用,就一个不行

解决方案 »

  1.   

    When you call a dynamic link library (DLL) function from Visual Basic for Windows, the "Bad DLL Calling Convention" error is often caused by incorrectly omitting or including the ByVal keyword from the Declare statement or the Call statement. The ByVal keyword affects the size of data placed on the stack. Visual Basic for Windows checks the change in the position of the stack pointer to detect this error. When Visual Basic for Windows generates the run time error "Bad DLL Calling Convention," the most common cause when calling API functions is omitting the ByVal keyword from the Declaration of the external function or from the call itself. It can also occur due to including the ByVal keyword when the function is expecting a 4 byte pointer to the parameter instead of the value itself. This changes the size (number of bytes) of the values placed on the stack, and upon return from the DLL, Visual Basic for Windows detects the change in the position of the stack frame and generates the error. 
      

  2.   

    楼上老兄说的,我也看了,但我用的都是ByRef,是不是就应该不需要考虑这个原因了呢函数原型bool __declspec(dllexport) CALLBACK export_DemandDetails_2(short *ItemID, short *Index, short &DemandItemID, double &Qty, long &OrderTime, long &DeliveryTime, short &OrderRefID, short &OrderType, double &CapReplyQty, double &StockQty)
    {
    return Model.get_DemandDetails2(*ItemID,*Index,DemandItemID,Qty,OrderTime,DeliveryTime,OrderRefID,OrderType,CapReplyQty,StockQty);
    }
    VB里声明和调用Declare Function export_DemandDetails_2 Lib "FabSim.dll" (ByRef ItemID As Integer, ByRef Index As Integer, ByRef DemandItemID As Integer, ByRef Qty As Double, ByRef OrderTime As Long, ByRef DeliveryTime As Long, ByRef OrderRefID As Integer, ByRef OrderType As Integer, ByRef CapReplyQty As Double, ByRef StockQty As Double) As BooleanIf export_DemandDetails_2(DemandItemID, DemandID, DemandItemID2, dblWQty, lngPlanTime, lngDelivTime, intOrderRefID, intOrderType, dblReplyQty, dblStockQty) ThenEnd If
      

  3.   

    函数原型要声明为 stdcall。
    参数引用要用 * 而不是 &。
    随 C 的版本不同,bool 可以是 1字节/4字节,对应 VB 的 Byte/Long,Boolean 是 2字节的。
    所有 VB 中的变量一定要显示声明类型。
      

  4.   

    Declare Function export_DemandDetails_2 Lib "FabSim.dll" (ByRef ItemID As Integer, ByRef Index As Integer, ByRef DemandItemID As Integer, ByRef Qty As Double, ByRef OrderTime As Long, ByRef DeliveryTime As Long, ByRef OrderRefID As Integer, ByRef OrderType As Integer, ByRef CapReplyQty As Double, ByRef StockQty As Double) As Long  
      

  5.   

    发现同样的代码在别人的电脑上可以,在我的电脑上不可以
    而且以前我也是可以用的
    我DEBUG了一下,发现DLL没有找到正确的函数名get_DemandDetails2,而是跳到另一个get函数去了
    不知道是啥原因
      

  6.   

    对两位老大的回答,我有点异议,我有一个函数和这个函数差不多,只是参数不多,但能用,请看下面的代码bool __declspec(dllexport) CALLBACK export_DemandDetails(short *ItemID, short *Index, short &DemandItemID, double &Qty, long &OrderTime, short &OrderRefID, short &OrderType)
    {
    return Model.get_DemandDetails(*ItemID,*Index,DemandItemID,Qty,OrderTime,OrderRefID,OrderType);
    }
    Declare Function export_DemandDetails Lib "FabSim.dll" (ByRef ItemId As Integer, ByRef Index As Integer, ByRef DemandItemID As Integer, ByRef Qty As Double, ByRef OrderTime As Long, ByRef OrderRefID As Integer, ByRef OrderType As Integer) As BooleanIf export_DemandDetails(intItemId, intDemandID, DemandItemID, dblQty, lngPlanTime, intOrderRefID, intOrderType) ThenEnd If
      

  7.   

    API 调用是很粗糙的,只是简单检查一下参数堆栈是否高度是否正确,所以看起来“调用成功”其实已经引起内存混乱了,get_DemandDetails2 的函数入口都不对了。
    API 难就难在错误不是运行出来的,而是预先想出来的。
      

  8.   

    我已经找到原因了
    是因为我把一个旧版本的DLL放到system32下了
    谢谢两位老大