VB calling DLL only with _stdcall?

  • Thread starter Thread starter bpsdg
  • Start date Start date
B

bpsdg

Hi,

I am currently still programming in VB6. On comp.lang.basic.visual.misc I
asked this question. And alhough there might be solutions, I wondered
whether this is also a problem in vb.net or isn't it?

Regards, Bas.
 
Cor Ligthert said:
Of course you can do that, it is the speciality from Dick, visit his
homepage

http://www.hardandsoftware.net/

Cor


I guess I am misunderstanding you, or you misunderstood my question. Dick's
specailty seems to be port communication. Although what I am trying to do
has to do with that, my question was about calling DLL functions from VB.
And in this case especially whether VB.net has the same problem with calling
functions that were not compiled with the _stdcall declaration that VB6
does.
 
I was reading this,
I am trying to get a VB program to communicate with a device that is
connected to an IR device which in turn is connected to COM1.
However the rest you can do as well, just search this newsgroup in Google
and you find many times your question (and the answers).

Cor
 
bpsdg said:
I am currently still programming in VB6. On comp.lang.basic.visual.misc I
asked this question. And alhough there might be solutions, I wondered
whether this is also a problem in vb.net or isn't it?

When using the 'DllImport' attribute to mark an external function call (to a
function residing in an unmanaged DLL) you can select the calling
convention. Unfortunately this does not work in VB6, only in VB.NET!
 
Herfried K. Wagner said:
When using the 'DllImport' attribute to mark an external function call (to
a function residing in an unmanaged DLL) you can select the calling
convention. Unfortunately this does not work in VB6, only in VB.NET!

Sounds good. I have a VB 2005 Express but didn't still care much for trying.
Now I will.
 
bpsdg said:
Sounds good. I have a VB 2005 Express but didn't still care much for
trying. Now I will.

First, it is possible to call non-stdcall functions in VB6. If you require I
have some code that will do this.
BUT, you don't need to do this. If you're getting away with calling one
single function without an error then they are using stdcall and it should
be compatible with vb6. You're likely just misreading the C++ code. It
sounds to me like you're making an error when retrieving data from the port.
How are you calling that particular function?
 
Michael C said:
First, it is possible to call non-stdcall functions in VB6. If you require
I have some code that will do this.
BUT, you don't need to do this. If you're getting away with calling one
single function without an error then they are using stdcall and it should
be compatible with vb6. You're likely just misreading the C++ code. It
sounds to me like you're making an error when retrieving data from the
port. How are you calling that particular function?

Okay, see the code at the bottom. I obscured some of the real variable names
etc., because I don't think I am allowed to share the exact code. I hope I
didn't make any typos while doing that.

I tried it in vb.net by the way (as Mr. Wagner suggested) and it works like
a charm. But I got a quite large app I am working on in VB6 from which it
should be a part of, so I am sill interested in your code.

In the function call in Command5_Click is returning true, but the values in
the debug. prints are all worng!

Module code:

Type XYZFILE
iSize As Integer
iTime As Integer
iDate As Integer
iDuration As Integer
bUSTimeMode As Boolean
iSamplingRate As Integer
bRRRecording As Boolean
bDeleted As Boolean
bSpeed As Boolean
bCadence As Boolean
bAltitude As Boolean
bPower As Boolean
bInterval As Boolean
szName As String * 11
iBike As Integer
iExerciseID As Integer
End Type

Declare Function fnCom_GetFileInfo _
Lib "xyzcom.dll" _
Alias "_fnCom_GetFileInfo@8" (ByVal iExercise As Integer, _
ByRef Exercise As XYZFILE) As Boolean


Form code:

Option Explicit

Private Sub Command5_Click()

Dim FileNummmer As Integer
Dim pef As XYZFILE

FileNummmer = 0

If fnCom_GetFileInfo(FileNummmer, pef) Then

Debug.Print
Debug.Print pef.bInterval
Debug.Print pef.bUSTimeMode
Debug.Print pef.iDate
Debug.Print pef.iTime
Debug.Print pef.iDuration
Debug.Print pef.iSamplingRate
Debug.Print pef.szName

MsgBox "File " & FileNummmer & " read!"

Else

MsgBox "Unable to read file!"

End If


End Sub


Thanks, Bas
 
bpsdg said:
Okay, see the code at the bottom. I obscured some of the real variable
names etc., because I don't think I am allowed to share the exact code. I
hope I didn't make any typos while doing that.

I tried it in vb.net by the way (as Mr. Wagner suggested) and it works
like a charm. But I got a quite large app I am working on in VB6 from
which it should be a part of, so I am sill interested in your code.

I'm a fan of dot net but I don't think there is any reason to use it in this
case if your app is all in vb6.
In the function call in Command5_Click is returning true, but the values
in the debug. prints are all worng!

Can you post the C++ definition of the XYZFILE struct? Possible problems
could be that it is expecting 32 bit integers when you are supplying 16 bit
integers (try using long instead of integer). The boolean might be a
different length to what C++ is expecting, the string is likely not in the
structure it is expecting and the offsets in the type are probably not what
it is expecting.

Michael
 
Michael C said:
Can you post the C++ definition of the XYZFILE struct? Possible problems
could be that it is expecting 32 bit integers when you are supplying 16
bit integers (try using long instead of integer). The boolean might be a
different length to what C++ is expecting, the string is likely not in the
structure it is expecting and the offsets in the type are probably not
what it is expecting.

Michael


typedef struct
{
int iSize;
int iTime;
int iDate;
int iDuration;
BOOL bUSTimeMode;
int iSamplingRate;
BOOL bRRRecording;
BOOL bDeleted;
BOOL bSpeed;
BOOL bCadence;
BOOL bAltitude;
BOOL bPower;
BOOL bInterval;
TCHAR szName[11];
int iBike;
int iExerciseID;
} XYZFILE;
 
Michael C said:
I'm a fan of dot net but I don't think there is any reason to use it in
this case if your app is all in vb6.

Well, I'm a hobbiest programmer but this app is relativily popular, so I'd
like it to last a few versions longer. I guess that I would have to make the
conversion to vb.net one day or the other.
 
Well, I'm a hobbiest programmer but this app is relativily popular, so I'd
like it to last a few versions longer. I guess that I would have to make the
conversion to vb.net one day or the other.

You know you can mix the two via com interop?
 
My knowledge of C is limited but int translates to long in vb and BOOL
appears to be the same thing as an int in C++ so that is a long in vb6 as
well. Because boolean in vb6 is 16 bit you will have to define them as longs
and then convert (or use them as they are). I'm not sure about the TCHAR but
I believe this is an ansi string on win9x and unicode on NT systems. If you
define it how you previously did then it might work on NT. Try this below
and let us know how you go. It should at least give the correct data up to
the string.

Type XYZFILE
iSize As Long
iTime As Long
iDate As Long
iDuration As Long
bUSTimeMode As Long
iSamplingRate As Long
bRRRecording As Long
bDeleted As Long
bSpeed As Long
bCadence As Long
bAltitude As Long
bPower As Long
bInterval As Long
szName As String * 11
iBike As Long
iExerciseID As Long
End Type
 
bpsdg said:
Well, I'm a hobbiest programmer but this app is relativily popular, so I'd
like it to last a few versions longer. I guess that I would have to make
the conversion to vb.net one day or the other.

Depends on your situation. Writing some of it in dot net can be a good way
to ease into the migration but it has a lot of downsides having 2 versions
of the same language. You need to deal with com interop issues and
distribute the vb6 and vb7 runtimes.
 
Michael C said:
My knowledge of C is limited but int translates to long in vb and BOOL
appears to be the same thing as an int in C++ so that is a long in vb6 as
well. Because boolean in vb6 is 16 bit you will have to define them as
longs and then convert (or use them as they are). I'm not sure about the
TCHAR but I believe this is an ansi string on win9x and unicode on NT
systems. If you define it how you previously did then it might work on NT.
Try this below and let us know how you go. It should at least give the
correct data up to the string.

Type XYZFILE
iSize As Long
iTime As Long
iDate As Long
iDuration As Long
bUSTimeMode As Long
iSamplingRate As Long
bRRRecording As Long
bDeleted As Long
bSpeed As Long
bCadence As Long
bAltitude As Long
bPower As Long
bInterval As Long
szName As String * 11
iBike As Long
iExerciseID As Long
End Type

You're fantastic Mr. C! That seems to work (just did a short test though). I
don't understand one bit about the _stdcall story anymore, but why should I
care? Maybe they declared the functions in the compiled version different
from the ones that are in the header files they gave me?
 
"Michael C" <[email protected]> schreef in bericht







You're fantastic Mr. C! That seems to work (just did a short test though). I
don't understand one bit about the _stdcall story anymore, but why should I
care? Maybe they declared the functions in the compiled version different
from the ones that are in the header files they gave me?- Hide quoted text -

- Show quoted text -

a lot of the time, you won't see _stdcall. it is often aliased using
to something else... Common aliases are WINAPI or PASCAL.
 
Tom Shelton said:
a lot of the time, you won't see _stdcall. it is often aliased using
to something else... Common aliases are WINAPI or PASCAL.

Don't see any of that. The function I was referring to in an earlier message
looks like this:

__declspec (dllexport) BOOL CALLBACK fnCom_GetFileInfo (HWND, int,
XYZFILE*);
 
bpsdg said:
Don't see any of that. The function I was referring to in an earlier
message looks like this:

__declspec (dllexport) BOOL CALLBACK fnCom_GetFileInfo (HWND, int,
XYZFILE*);

C++ has the define statement. I think it would be an understatement to say
it was overused and abused (there must be 10 ways to define a 32bit int).
The word CALLBACK will be defined somewhere and most likely includes stdcall
as part of its definition. Look for a statement like this (might have 1 or 2
underscores, can't remember).

#define CALLBACK _stdcall balh blah

It could also be point to another define like this:

#define CALLBACK WINAPI
and somewhere else
#define WINAPI stdcall blah blah

Michael
 
"Tom Shelton" <[email protected]> schreef in bericht



Don't see any of that. The function I was referring to in an earlier message
looks like this:

__declspec (dllexport) BOOL CALLBACK fnCom_GetFileInfo (HWND, int,
XYZFILE*);

CALLBACK is another #define that usually means __stdcall. It is most
likely importing the standard windows headers, and in Windef.h:

#define CALLBACK __stdcall
 
Michael C said:
C++ has the define statement. I think it would be an understatement to say
it was overused and abused (there must be 10 ways to define a 32bit int).
The word CALLBACK will be defined somewhere and most likely includes
stdcall as part of its definition. Look for a statement like this (might
have 1 or 2 underscores, can't remember).

#define CALLBACK _stdcall balh blah

It could also be point to another define like this:

#define CALLBACK WINAPI
and somewhere else
#define WINAPI stdcall blah blah

Non of that, but I think I only got the code that is important to use the
DLL. As far as I understand it's not the complete code from which the DDL
was compiled.
 
Back
Top