mairouka
asked on
calling dll from vb6 with struct argument
Hi!
I'm trying to pass a struct from vb6 to a c dll and write it over an existing struct in the dll
I've written the code below:
in vb------------------------ ---------- ---------- --
Option Explicit
Private Declare Sub func Lib "c:\StrSamp.dll" _
(s As mpa)
Private Type mpa
a As Integer
b As Integer
c As String
End Type
Dim m As mpa
Private Sub Form_Load()
m.a = 2
m.b = 4
m.c = "xexe"
func m
End Sub
and in c dll----------------------- ---------- ---------
in a header file m , i have stored the struct
m.h
typedef struct __S{
int m;
int n;
char *o;
}S;
and in the cpp file of the dll i have the following code:
#include <windows.h>
#include "m.h"
void __stdcall func(S d)
{
MessageBox(NULL,"ok struct!","progress",MB_OK) ;
MessageBox(NULL,d.o,"membe r_of_struc t",MB_OK);
}
-------------------------- ---------- ---------- --
it doesn't work properly.after it prints message_box "xexe",i get an
error message:
" Run-time error 149'
Bad DLL calling convention "
how can this program work?
please,help!
:o(
I'm trying to pass a struct from vb6 to a c dll and write it over an existing struct in the dll
I've written the code below:
in vb------------------------
Option Explicit
Private Declare Sub func Lib "c:\StrSamp.dll" _
(s As mpa)
Private Type mpa
a As Integer
b As Integer
c As String
End Type
Dim m As mpa
Private Sub Form_Load()
m.a = 2
m.b = 4
m.c = "xexe"
func m
End Sub
and in c dll-----------------------
in a header file m , i have stored the struct
m.h
typedef struct __S{
int m;
int n;
char *o;
}S;
and in the cpp file of the dll i have the following code:
#include <windows.h>
#include "m.h"
void __stdcall func(S d)
{
MessageBox(NULL,"ok struct!","progress",MB_OK)
MessageBox(NULL,d.o,"membe
}
--------------------------
it doesn't work properly.after it prints message_box "xexe",i get an
error message:
" Run-time error 149'
Bad DLL calling convention "
how can this program work?
please,help!
:o(
This is kind of off the cuff... but I'm half thinking that you shouldn't have dynamic strings in your structs when passing between VB and C.
Your code has several improvements/bugs:
1- Pass structure by reference
2- char* is not the same than a string. VB strings and C strings are completely different.
3- Better use longs instead of ints
Your code working
VB Code:
Option Explicit
Private Declare Sub func Lib "c:\StrSamp.dll" _
(ByVal s As Long)
Private Type mpa
a As Long
b As Long
c(1 To 50) As Byte
End Type
Dim m As mpa
Sub VBStrToCharP(strIn As String, strOUT() As Byte)
Dim n As Long
For n = 1 To Len(strIn)
strOUT(n) = Asc(Mid(strIn, n, 1))
Next
'strings in C are zero ended
strOUT(n) = 0
End Sub
Private Sub Form_Load()
m.a = 2
m.b = 4
StrToCharP "xexe", m.c
func VarPtr(m)
End Sub
C Code:
typedef struct __S{
long a;
long b;
char c[50];
}S;
void _stdcall func(S* d)
{
char Dummy[500];
MessageBox(NULL,"ok struct!","progress",MB_OK)
sprintf(Dummy,"a=%d",d->a)
MessageBox(NULL,Dummy,"mem
sprintf(Dummy,"b=%d",d->b)
MessageBox(NULL,Dummy,"mem
MessageBox(NULL,d->c,"memb
}
Regards
sorry
line StrToCharP "xexe", m.c
should be
line VBStrToCharP "xexe", m.c
line StrToCharP "xexe", m.c
should be
line VBStrToCharP "xexe", m.c
When you pass a user defined struct from VB to a C or C++ or Windows API you should declare the function as Any.
that is the function declration should be
Private Declare Sub func Lib "c:\StrSamp.dll" _
(BYVAL s As Any)
The second option is
Declare the function with the member variables of the structure itself that is
Private Declare Sub func Lib "c:\StrSamp.dll" _
(Byval m as Integer,Byval n as integer, Byval o as string)
Vb will automatically pass the correct structure when you call the function
I hope it will work
that is the function declration should be
Private Declare Sub func Lib "c:\StrSamp.dll" _
(BYVAL s As Any)
The second option is
Declare the function with the member variables of the structure itself that is
Private Declare Sub func Lib "c:\StrSamp.dll" _
(Byval m as Integer,Byval n as integer, Byval o as string)
Vb will automatically pass the correct structure when you call the function
I hope it will work
ASKER
thank you! it really worked!
but what if, i write " unsigned char c " instead of " char c[50] " in struct S in my c code?
Doing so,i come up to problems again....!
i intend to use types unsigned char and unsigned short in my c code,as i want it to be compatible with a code i've already written.
is there any advise?
thanx again!
but what if, i write " unsigned char c " instead of " char c[50] " in struct S in my c code?
Doing so,i come up to problems again....!
i intend to use types unsigned char and unsigned short in my c code,as i want it to be compatible with a code i've already written.
is there any advise?
thanx again!
ASKER
thank you! it really worked!
but what if, i write " unsigned char c " instead of " char c[50] " in struct S in my c code?
Doing so,i come up to problems again....!
i intend to use types unsigned char and unsigned short in my c code,as i want it to be compatible with a code i've already written.
is there any advise?
thanx again!
but what if, i write " unsigned char c " instead of " char c[50] " in struct S in my c code?
Doing so,i come up to problems again....!
i intend to use types unsigned char and unsigned short in my c code,as i want it to be compatible with a code i've already written.
is there any advise?
thanx again!
Struct in C and type in VB must be the same. What means the same?
Each member of struct in two languages must have same lenght in bytes if you want to directly handle this struct.
Each data type has its own lenght and in VB for example, an string has dynamic lenght. Then this data type is not suitable to use in VB types to pass structures to C. This don't mean that a VB string can't be passed to C, only is not suitable. As a single parameter can be easily passed to C, and inside an structure can be handled in C with some code, but what we want here is to directy handle structure.
To make things harder, not only must have same lenght in bytes it must have same bit convention, i.e. signed/unsigned and order of bytes. Remember we are always talking to DIRECTLY handle structs.
Take a look here to see C types
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/reftable_1.asp
and here to VB types
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbenlr98/html/vagrpDataType.asp
Be very carefully when writing in struct within C code not to pass struct bounds. If you do it, results are unpredictible, VB IDE can crash,....
Hope this clarifies things a bit.
Cheers
Each member of struct in two languages must have same lenght in bytes if you want to directly handle this struct.
Each data type has its own lenght and in VB for example, an string has dynamic lenght. Then this data type is not suitable to use in VB types to pass structures to C. This don't mean that a VB string can't be passed to C, only is not suitable. As a single parameter can be easily passed to C, and inside an structure can be handled in C with some code, but what we want here is to directy handle structure.
To make things harder, not only must have same lenght in bytes it must have same bit convention, i.e. signed/unsigned and order of bytes. Remember we are always talking to DIRECTLY handle structs.
Take a look here to see C types
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/reftable_1.asp
and here to VB types
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbenlr98/html/vagrpDataType.asp
Be very carefully when writing in struct within C code not to pass struct bounds. If you do it, results are unpredictible, VB IDE can crash,....
Hope this clarifies things a bit.
Cheers
ASKER
sorry but with unsigned char and unsigned short types the same programm doesn't work and the site didn't help me much.....any example? any idea?
i would appreciated it,if somebody could give me a hint!
i would appreciated it,if somebody could give me a hint!
Please, can you give further details about what you intend to do?
ASKER
I write the interface(in vb) of a network device. i have the code of the protocol the device uses , in c and writting now the interface in vb. From vb i call the routines of the protocol with the form of dll's. I want now to pass a struct from vb in a dll so that after tha call the fields of the vb struct are written over the fields of the struct used in c. The c struct has types of form unsigned char and unsigned short,so i have to use in my vb application some matching types to these . I have tried and haven't done anything much....! I can't change the types in the c code....so.....!
Ok you have problems with unsigned char and unsigned short in C, but from which VB types are you trying to translate??
Post VB type you actually have and C struct that you cannot change and I'll give you code to translate it...
Post VB type you actually have and C struct that you cannot change and I'll give you code to translate it...
ASKER
because the struct has too many fields i gine you a sub_struct of the original one:
in the c code the struct is:
typedef struct __communityId {
char name[3];
int n;
int o;
}communityId;
typedef struct __M {
unsigned char a[6];
unsigned char b[4];
unsigned char c[4];
unsigned char d[4];
unsigned char e;
unsigned char f;
unsigned char g[32];
unsigned char h;
unsigned char i[4][13];
unsigned char j[6];
unsigned char k;
unsigned char l[4];
communityId communities[3];
unsigned char m[16];
}M;
in the vb code the struct is:
Type x
onoma As String
n As Integer
o As Integer
End Type
Type m
a(1 To 6) As Variant
b(1 To 4) As Variant
c(1 To 4) As Variant
d(1 To 4) As Variant
e As String
f As Variant
g As Variant
h As Variant
i(1 To 4, 1 To 13) As Variant
j(1 To 6) As Variant
k As Variant
l(1 To 4) As Variant
community(1 To 3) As x
m As Variant
End Type
the vb struct m fills it's fields from text boxes,combo,check boxes etc. from user inserted values.
for this struct some possible values would be
0x0 0x1 0x2 0x3 0x4 0x5 // a
10 170 254 1 // b
255 255 255 255 // c
0 0 0 0 // d
0 // e
0 // f
"company" // g[32]
0 //h
0 0 0 0 0 0 0 0 0 0 0 0 0 // i1
0 0 0 0 0 0 0 0 0 0 0 0 0 // i2
0 0 0 0 0 0 0 0 0 0 0 0 0 // i3
0 0 0 0 0 0 0 0 0 0 0 0 0 // i4
0 0 0 0 0 0 // j[6]
0 // k
0x82 0x84 0x8b 0x96 //l[4]
"one" //community member 1
0
6
"two" //community member 2
0
6
"three" //community member 3
0
6
"A" //m
from vb i call
Private Declare Function Initialization Lib "C:\func.dll" (ByVal s As Any) As Integer
and somewhere in the code when the m struct is filles
func VarPtr(m)
and in the c code:
somewhere in a header there is:
extern M x
and in the code where the func is
extern "C" __declspec(dllexport) int func (M* x)
{
// code lines
}
waiting for your reply!!! :)
in the c code the struct is:
typedef struct __communityId {
char name[3];
int n;
int o;
}communityId;
typedef struct __M {
unsigned char a[6];
unsigned char b[4];
unsigned char c[4];
unsigned char d[4];
unsigned char e;
unsigned char f;
unsigned char g[32];
unsigned char h;
unsigned char i[4][13];
unsigned char j[6];
unsigned char k;
unsigned char l[4];
communityId communities[3];
unsigned char m[16];
}M;
in the vb code the struct is:
Type x
onoma As String
n As Integer
o As Integer
End Type
Type m
a(1 To 6) As Variant
b(1 To 4) As Variant
c(1 To 4) As Variant
d(1 To 4) As Variant
e As String
f As Variant
g As Variant
h As Variant
i(1 To 4, 1 To 13) As Variant
j(1 To 6) As Variant
k As Variant
l(1 To 4) As Variant
community(1 To 3) As x
m As Variant
End Type
the vb struct m fills it's fields from text boxes,combo,check boxes etc. from user inserted values.
for this struct some possible values would be
0x0 0x1 0x2 0x3 0x4 0x5 // a
10 170 254 1 // b
255 255 255 255 // c
0 0 0 0 // d
0 // e
0 // f
"company" // g[32]
0 //h
0 0 0 0 0 0 0 0 0 0 0 0 0 // i1
0 0 0 0 0 0 0 0 0 0 0 0 0 // i2
0 0 0 0 0 0 0 0 0 0 0 0 0 // i3
0 0 0 0 0 0 0 0 0 0 0 0 0 // i4
0 0 0 0 0 0 // j[6]
0 // k
0x82 0x84 0x8b 0x96 //l[4]
"one" //community member 1
0
6
"two" //community member 2
0
6
"three" //community member 3
0
6
"A" //m
from vb i call
Private Declare Function Initialization Lib "C:\func.dll" (ByVal s As Any) As Integer
and somewhere in the code when the m struct is filles
func VarPtr(m)
and in the c code:
somewhere in a header there is:
extern M x
and in the code where the func is
extern "C" __declspec(dllexport) int func (M* x)
{
// code lines
}
waiting for your reply!!! :)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
mairouka:
This old question needs to be finalized -- accept an answer, split points, or get a refund. For information on your options, please click here-> http:/help/closing.jsp#1
EXPERTS:
Post your closing recommendations! No comment means you don't care.
This old question needs to be finalized -- accept an answer, split points, or get a refund. For information on your options, please click here-> http:/help/closing.jsp#1
EXPERTS:
Post your closing recommendations! No comment means you don't care.
with your help people , i finally solved my problem...... thanx for the advice!
:) :) :) :)
:) :) :) :)
little_mg is mairouka ! i have changed my nick_name! ;-)
No Comment has been added lately, so it's time clean to up this TA.
I will leave a recommendation in the CleanUp topic area:
[Accept Smallint's comment as answer]
Please leave any comments here within the next seven days.
Visit the URL if u require help on closing the question.
https://www.experts-exchange.com/help/closing.jsp
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
srimanth
EE CV
I will leave a recommendation in the CleanUp topic area:
[Accept Smallint's comment as answer]
Please leave any comments here within the next seven days.
Visit the URL if u require help on closing the question.
https://www.experts-exchange.com/help/closing.jsp
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
srimanth
EE CV