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.
楼上老兄说的,我也看了,但我用的都是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
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
对两位老大的回答,我有点异议,我有一个函数和这个函数差不多,只是参数不多,但能用,请看下面的代码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
API 调用是很粗糙的,只是简单检查一下参数堆栈是否高度是否正确,所以看起来“调用成功”其实已经引起内存混乱了,get_DemandDetails2 的函数入口都不对了。 API 难就难在错误不是运行出来的,而是预先想出来的。
{
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
参数引用要用 * 而不是 &。
随 C 的版本不同,bool 可以是 1字节/4字节,对应 VB 的 Byte/Long,Boolean 是 2字节的。
所有 VB 中的变量一定要显示声明类型。
而且以前我也是可以用的
我DEBUG了一下,发现DLL没有找到正确的函数名get_DemandDetails2,而是跳到另一个get函数去了
不知道是啥原因
{
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
API 难就难在错误不是运行出来的,而是预先想出来的。
是因为我把一个旧版本的DLL放到system32下了
谢谢两位老大