Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17


Interfacing a dll written in c++

Posted on 2002-04-16
Medium Priority
Last Modified: 2010-05-02
Hi everyone,
I got a stupid problem again and dunno howto handle it.

I wrote a dll in VC++ the contains this function
... ImageRead(  char* fname,
                unsigned char** Image,
          int* fmt,
          int* width,
          int* height,
          int* resolution,
          int* color,
          unsigned char** map);
The first parameter is only needed to be given, the others are filled by the function.

In VB, I implemented it the following way:

Public Declare Function ImageRead Lib "myImage.dll" (ByRef fileName As Integer, _
ByRef imgData() As Byte, _
ByRef format As Integer, _
ByRef width As Integer, _
ByRef height As Integer, _
ByRef resolution As Integer, _
ByRef color As Integer, _
ByRef map() As Byte) As Long

When I try to call this function I always get a 'Runtime error 13' type mismatch.

Whats my freakin' mistake??
Thanks in advance!!!

Question by:ulf_k
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions

Author Comment

ID: 6944403
Edit: Sorry, I'm stupid.
It has to be 'ByRef fileName As String'
but still I get an error 'Runtine error 49, bad dll calling convention'
Any ideas?

Greetings, Ulf.

Expert Comment

ID: 6944438
Strings are represented in C by the LPSTR data type (pointer to characters). Visual Basic can pass these parameters by using the (ByVal paramname As String) or (ByVal paramname$) conventions.

Expert Comment

ID: 6944457
I am not a C++ programmer but I found this example in

From talking to the author of this dll I know that you need to do somthing to be able to use a dll in VB. I believe this is an example of it but I could be wrong.

__declspec ( dllexport ) int WINAPI PlanB_E_Mail(char *server, char *emailAddr, char *fromUser, char *fromDomain, char *subject, char *xmailer, char *message );

I can email you the complete example if you like.

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.


Expert Comment

ID: 6944502
I know when you are using API's you should geberally stay away from using a variable ByRef because they will generally use the adress in memory for the variable instead of the actual variable value.  What you might want to do.... Which I have never done....  use the refernces and create an object.....  I do not know if you can do that with the function you have...

That is my best shot

Expert Comment

ID: 6944580
Dear ulf_k

If the dll written in vc++, the functions has to follow the naming convention _stdcall if you want to call it from VB. Try it. Hope this helps.


Expert Comment

ID: 6944644

You have to use ByVal passing strings so VB can make the necessary conversions (Unicode - Ansi and so on)
LVL 18

Expert Comment

ID: 6944728
To clarify a couple of things...

VB always passes strings to C or C++ dlls By Reference, even if you use the ByVal keyword.  The difference, and why it is important to use the ByVal keyword anyway, is that when you use ByVal, VB attaches a null-termination character to the end of the string, which most C or C++ functions will look for to know where the end of the string is.  Some C or C++ functions don't look for a null-termination character, and perhaps rely on the caller to pass the length of the string as another parameter, so in those cases, you'd want to pass the string ByRef.

Now, about the other things.  First, there is a difference between Visual Basic and C/C++ in their default "calling convention".  C/C++ uses the C/C++ calling convention and VB uses the "pascal" calling convention (the calling convention tells the function what order to pull the parameters off the stack).  In order to get a C/C++ dll to use the pascal calling convention it needs to be declared with the syntax shown above:

int WINAPI PlanB_E_Mail(char *server

or, I think that WINAPI is also just a constant for:

int _stdcall PlanB_E_Mail(char *server

One more thing, C++ "mangles" the name of a function when it is compiled.  So, if your function was:

PlanB(int x, int y)

Then when compiled, it will internally be renamed to something like:


This is because C++ allows for overloading (or is it overriding) where you can have two functions with the same name but different parameters.  So, you could also have:


And that would become PlanBInt internally, allowing both functions to exist together.  If you want to make the function available to external applications, then you have to make sure that the compiler doesn't mangle the name, and the way you do this is with the Extern C declaration.  Sorry I don't have an example.

Expert Comment

ID: 6944789
Hi, one of the reasons you have to pass strings ByVal not yet mentioned is that a string in VB is a pointer to the string in memory. If you pass a string ByRef, you are in fact passing a pointer to that pointer. If you pass it ByVal, then you pass the pointer itself.



Expert Comment

ID: 6944845
A final note on strings

Visual Basic stores strings internally as Unicode strings. When you call a DLL function, VB makes a temporary ANSI copy of the string (among others, this is terminated with a NULL character). When the function returns, it converts this temporary ANSI string back into Unicode. The problem? The DLL function receives the address of the ANSI string, which is the address of a temporary buffer. As soon as the function returns, the buffer is no longer valid. Thus, any function that obtains the address of a string by passing the string to a DLL will not return a useful value.

If you have MSDN see :
Book Excerpts - Win32 API programming with VB

Author Comment

ID: 6977015
Sorry for the l8 answer.
You all gave me some interesting points. Now it comes to the difficulty in my dll.
I declared a 'unsigned char** image' & 'unsigned char** map' in the c-interface. Anybody who can tell me, how to interface this to vb will get the 100 points. Coz I'm sitting here many hours in front of my puter, researching the web for the answer, but found nothing yet.
And many thanks to all you guys for helping me!!!


Expert Comment

ID: 6977061

the address of var, returned as a long.


Author Comment

ID: 6977083
Thanx for the fast answer, but my app wont swing this way.
I call the dll function like this
dim imagedata(5000) as Byte
dim map(5000) as Byte
ret = ImageRead("c:\none.rgb", VarPtr(imagedata), format, width, height, resolution, color, VarPtr(map))

and the compiler nags me with a type mismatch error for 'VarPtr(imagedata)', so i assume there's something missing. Could you please gimme another hint?

Thanks in advance.

Expert Comment

ID: 6977130
sorry, I saw you declared them as uchar and varptr returns a long

Beats me, I'll think somemore about it

Expert Comment

ID: 6977638
Just another thought on the the string passing.
I personally like doing it:
Private Declare APIFuncW(ByVal TheString as long,...
Private Declare APIFuncA(ByVal TheString as long,...



This leaves no ambiguity about exactly what is being passed.

as far as the handle passing, I think you have to do something like this:

Dim X(5000) as Byte
Dim pX as Long, hX as Long


Arrays in VB are not like C arrays. The VarPtr of an Array
DOES NOT point to the start of the data. It points to an array descriptor. (They are "SAFEARRAYS"). ISee Curland's book, "Advanced Visual Basic 6" for a good explanation of VB internals.

Also, the above method may lead to the handle being invalid if the data is moved by the OS.  I stongly suggest you store the data in a buffer you allocate from the OS outside the VB memory management, so you can get a true handle.

LVL 49

Expert Comment

ID: 7654106
Hi ulf_k,
It appears that you have forgotten this question. I will ask Community Support to close it unless you finalize it within 7 days. I will ask a Community Support Moderator to:

    Save as PAQ -- No Refund.

ulf_k, Please DO NOT accept this comment as an answer.
EXPERTS: Post a comment if you are certain that an expert deserves credit.  Explain why.
DanRollins -- EE database cleanup volunteer

Accepted Solution

SpideyMod earned 0 total points
ID: 7755103
per recommendation

Community Support Moderator @Experts Exchange

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question