Using a DLL function getting Bad DLL calling convention

I am trying to use the following function in a DLL I have also supplied my code.

Function in DLL

**********************************************************************************************************
* ResetBCBoard()
*
* Function:     This function is to reset a BC board
*
* Parameters:   Input:  cIesID -- IES module ID to which the BC is connected  
*                       cGroupNum -- Group number on which the BC is in
*               Output: None
*
* Logical Control: Put this function number, data length to be sent and data length expected
*                      into the function structure
*                  Call function BasicBCSetValue() to communicate to the IES
*
* Returns: returned value from function BasicBCSetValue()
*
***********************************************************************************************************/
DLLFUNCTION short ResetBCBoard(unsigned char cIesID, unsigned char cGroupNum)
{
    // declare function structure
    FUNCTION_STRUCT structResetBCBoard;

    structResetBCBoard.cFunctionNumber = 0x092;
    structResetBCBoard.nRequestDataLen = 1;     // size of cGroupNum
    structResetBCBoard.nResponseDataLen = 0;

    //call basic BC set value function
    return (BasicBCSetValue(cIesID, cGroupNum, structResetBCBoard,  NULL));

}
My code

    Private Declare Function ResetBCBoard Lib _
    "K:\lou\api\release\iesctrl.dll" _
    (ByVal cIesID As String, ByVal cGroupNum As String) As Integer


Private Sub Command1_Click()
    x = ResetBCBoard("1", "1")
End Sub
louyAsked:
Who is Participating?
 
prozakCommented:
When creating a DLL in C for VB there are several things you need to do. First, if you are compiling a C++ file you must put 'extern "C"' in front of every function that is being called by VB. In addition to that, all functions must be compiled using the _stdcall option. This controls how arguments are passed to the C function.  Also, when I compiled DLLs to use with VB5 and VC5, I had to create a separate .DEF file to export the functions. Now that I have said that on to the DLL.

It sounds like you modified the parameters in the .C file and not in the .H file. (Referring to the "redefinition" error"). What I would suggest is the follows. If you're only trying to pass one character as the parameter, declare you C function like this:

DLLFUNCTION short _stdcall ResetBCBoard(unsigned char clesID, unsigned char cGroupNum)

And declare you're VB function like this:

Declare Function ResetBCBoard Lib "dllname.dll" (ByVal clesID As Byte, ByVal cGroupNum As Byte)

That should work great if you're only passing on character per parameter. If you're trying to pass in strings, you need to do it like this:

DLLFUNCTION short _stdcall ResetBCBoard(char *clesID, char *cGroupNum)

And declare you're VB function like this:

Declare Function ResetBCBoard Lib "dllname.dll" (ByVal clesID As String, ByVal cGroupNum As String)

If you do need to pass a string and not just one character, be sure to modify the declaration of ResetBCBoard in your .H file (probably APNES.H) to reflect the above declaration. That's why you were getting the "redefinition" error. Hope this helps...
0
 
MikeP090797Commented:
Try declaring the parameters as byte instead of string. The function also must be compiled using stdcall calling convention, you can specify them in the settings of the projects of the dll (Alt+F7 in VC)
0
 
louyAuthor Commented:
Tried Byte and that did not work.  I called another function in the DLL that needed no paramaters and it returned a value OK.  I did not write the C program and have limited knowledge of C.  I am still working on it.  Any other suggestions?
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
louyAuthor Commented:
Tried the stdcall option in the compile which was I think Gz, but got a compile error.
0
 
khaledcCommented:
Declare two strings variables and  declare x as followed:
Dim str1 as string
Dim str2 as string
Dim x as integer
    str1="1"
    str2="1"
    x = ResetBCBoard("1", "1")
One mistake I could see is non matching variable type between the function and x value, therefore x should have same number of bytes as the function. It can be done by declaring x as the same type as the function.
0
 
chris_aCommented:
The correct declare is:

Private Declare Function ResetBCBoard Lib _
    "K:\lou\api\release\iesctrl.dll" _
    (ByVal cIesID As Byte, ByVal cGroupNum As Byte) _
    As Integer

If this fails your DLL is compiled wrongly
0
 
twardCommented:
Try to change your function to the following:

#define NOMANGLE

short NOMANGLE _stdcall
ResetBCBoard(unsigned char cIesID, unsigned char cGroupNum)

I have many DLL's written in C that I use and as far as I know the above is how you have to declare your functions in C.
0
 
louyAuthor Commented:
I am not familiar with C.  I tried making the _stdcall changes and the program would not compile.  I get the following IES.C
K:\Lou\API\IES.C(2784) : error C2373: 'ResetBCBoard' : redefinition; different type modifiers
Error executing cl.exe.

IES.OBJ - 1 error(s), 0 warning(s)

Can you be more specific on the changes to the c program.

I tried changing the parameters to Byte and that did not work.

Any other suggestions anybody.  I hate C...
0
 
twardCommented:
What C Compiler are you using?  If you Email it to me I can get it to work, send it back to you and post what needed to be changed here...  (tward@msii.com)
0
 
twardCommented:
What C Compiler are you using?  If you Email it to me I can get it to work, send it back to you and post what needed to be changed here...  (tward@msii.com)
0
 
louyAuthor Commented:
We are making progress.  Now my VB error is #453 can't find DLL entry point for ResetBCBoard

I made the following change to the .C and .H and it compiled. like you suggested.
DLLFUNCTION short _stdcall ResetBCBoard(unsigned char cIesID, unsigned char cGroupNum);

Here is my VB code

Option Explicit
    Dim y, z    As Byte
    Dim x As Integer
    'Dim cIesID As String * 1
    'Dim CGroupNum As Byte
    Private Declare Function ResetBCBoard Lib _
    "a:\testAPI\iesctrl.dll" _
    (ByVal cIesID As Byte, ByVal CGroupNum As Byte) As Integer

Private Sub Command1_Click()
    y = 1
    z = 1
    x = ResetBCBoard(y, z)  
    'x = ResetBCBoard("1", "1")
End Sub

0
 
prozakCommented:
What you need to do now is modify the definition (.DEF) file to export the function from the DLL so it is callable by external programs. You should have a .def file as part of you project if you don't you can create one with note pad.

The format is as follows:

LIBRARY iesctrl
EXPORTS
  ResetBCBoard @1

The "@1" is the ordinal position of the exported function. If you already have exported functions in the .DEF file you can add more lines and just make the position one more than the preceding function. For example

LIBRARY iesctrl
EXPORTS
  some_function_1 @1
  some_other_function @2
  ResetBCBoard @3

That should get rid of your can't find DLL entry point error.
0
 
louyAuthor Commented:
that worked Thank you

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.