03-18-2010 05:04 AM
Hi,
the attached fiel contains an experimen to read dll made in LV 8.6 and use it in VB6.
The zip file contains the vi (adding 2 numbers), LV project, VB6 project.
The function seems to work. it adds the numbers but still, it gives the error 'Bad dll calling convention'.
I think I made it right. i used the Standard Calling Conventioin. I used Double in LV and Long in VB.
how do I get rid from this error?
Can sombody use this example on his machine. May be it's something to do with my specific machine?
Solved! Go to Solution.
03-19-2010 02:54 PM
Hello,
Can you give a screenshot of the error? Do you get the same thing when you use an I16? Could you go over this devzone and try the code again? Also can you specify which version of Visual Studios you are using? Also, what version of LV were you using to build your dll?
Regards,
Andrew Eddleman
03-21-2010 11:47 PM
VB usually gives the "bad DLL calling convention" error when you have declared a function incorrectly. This can be as simple as exporting with __cdecl instead of __stdcall (although this will more likely just crash) or it could be that due to the function declaration being wrong, the stack gets placed in a funny state because the DLL call placed more/less data on the stack than VB expected based on your declaration.
In your specific case, I see a few problems. For reference:
In LabVIEW, your C equivalent function prototype as shown in your project file is:
double AddNumbers(double *xY, double x, double y)
In VB, your declaration is:
Declare Sub AddNumbers Lib "D:\NI Projects\eDAS400\DLL\LVDLL Experiment\SharedLib.dll" _
(ByVal x As Double, ByVal y As Double, xy As Double)
The first "double" in the C prototype means that the function call into the DLL is going to return a double. In your VB prototype, by declaring it as a "Sub" you are, in essence, telling VB that you don't expect the DLL to return data. This is one likely cause of your error. To fix this, change it to say "Declare Function" and then add "As Double" at the end of the declaration.
The second problem that I see is that in your C prototype, the first parameter is being passed by reference (as a pointer). Your VB declaration, however, is passing everything ByVal. You need to modify this so that the parameter that returns data (xY in this case) is being passed ByRef.
Finally, it looks like your parameters in the C function are probably not in the order you expect. I would expect them to be x, y, xy (as you have in the VB declaration) but the order in the C function (ie. in the DLL) isn't the same. This will cause funny behavior. The order should match between the two. To fix this one, I would actually recommend changing the LV DLL so that the parameters are exported in the more logical x, y, xy order.
I think that this should take care of your issues. Sorry so long winded but I wanted to make sure that you understood the "why" on this one because it can be a common error when trying to create/call DLLs from VB.
Jason
03-22-2010 05:25 PM
Hi Jaicon,
Thank you so much for your help. The dll is working now.
I made one step further and put a string as in input. I'm trying now to display this message (actually a concatenation of this msg and another constant msg from the vi).
I get no errors by I get no messages. Can you look at it please?
I tried to use: C string type and Pascal string type, Both resulted in the same way. no response....
Thanks
Rafi
03-23-2010 08:29 AM
Rafi,
I see your VB code but I think that you may not have included the latest version of your VI's and LabVIEW project because I don't see the string input on that side of things.
From a VB perspective
If all of this doesn't work, try repackaging up your zip file with all of the LV project and I'll take another look to see if there's anything obvious going on from that end.
Jason
03-23-2010 12:55 PM
Hi Jason,
thank you so much for your help....
you are right, the vi was not the one I used in the project (My project pointed to the vi on my desktop). The attached zip contains the correct vi.
I followed your advice to add the NULL ch. at the end of the message I'm sending to the dll.
No change. Still no message is displayed by the vi.
I'm not very skilled in LV, so, it is possible that I made some stupid mistake there.
thanks
Rafi
03-24-2010 01:30 PM
Rafi,
I took a look at your code and I think that the problem may be in your expectation of what's going to happen. At the point that you build into a DLL, your AddNumbers VI becomes a function call. You are then passing a string into that function call but you don't have anything coming back out of it.
As an experiment, I took your VI and wired the "concatenated string" output to one of the icon terminals and then added a function export for it in the DLL function. It looked something like the following (both the C prototype and the VB equivalent):
' void AddNumbers(double x, double y, char string[], double *xY, char concatenatedString[], int32_t len)
Declare Sub AddNumbers Lib "C:\Users\jasonw.AMER\Desktop\LVDLL Experiment\SharedLib.dll" _
(ByVal x As Double, ByVal y As Double, ByVal myMsg As String, ByRef xy As Double, ByVal outString As String, ByVal stringLength As Long)
I then tested calling that function and I think it's safe to say that it's properly passing strings because I was able to get the returned string of "the message recevied by the dll is.....My First Message". Here's what my calling code looked like:
Dim outStr As String * 100
Call AddNumbers(x, y, "My First Message", xy, outStr, 100)
Debug.Print outStr
So I think it's working properly. There's no need to append the null character apparently (although I did notice in your code that you had enclosed the Chr(0) in quotes...it should be without quotes to properly give a null character...but you can leave it out altogether).
Long story short, your code probably was working right. Hope that helps.
Jason
03-24-2010 03:26 PM
Hi Jason,
Thank you very very much... Your explanations are most helpful. Not only that you figured out my problem , you also showed me how VB get a string from LV which was going to be my next step.
I still have a major issue here.... My expectation were to display something from LV. What you've seen is just a practice exercise. My objective is to perform signal analysis with LV, while VB provides some numbers and a path to a file of signal data. The objective is to perform the analysis and, to display the graphs.
Did I understood you correctly, that a dll can only be used as a function call to return some value?
Is there any way to display that graph? ... or in my experimental project, to display the text message?
Thanks again
Rafi
03-25-2010 08:22 AM
Rafi,
You most certainly CAN show the front panel of the VI that you are calling. There's an example of doing this at:
http://zone.ni.com/devzone/cda/epd/p/id/1887
It's pretty straightforward, really. All you need to do is set the VI properties such that the front panel is shown when called. Optionally, you can have it close when finished. To do this, right click on the VI's icon (upper right corner of window) from either the front panel or block diagram editor and choose "VI properties". Select the "window appearance" category and then click on the customize button. Check the "Show front panel when called" option. That's it!
Remember that from VB's perspective, it is just making a function call and that function call is going to return pretty quickly the way it's written right now. There are LabVIEW options to leave the front panel open after the function call (in the same dialog as above). You might also need to add some code into your VI so that there's a "Done" button or something like that. This will cause VB to essentially hang inside of the function call until your user says that they are done with the dialog that was popped up from LabVIEW.
Jason
03-26-2010 11:02 PM
Hi Jason,
Thank you very much.
Finally i got it to work...both the string to be displayed by the dll and to return the outstring back to visual basic.
Thanks again
Rafi