Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0 
Author Message
 Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0



Quote:
>I am trying to write a simple DLL in MS visual C(++) version 4.0 to be
>called by MS Visual Basic Version 4.0.

>I've successfully generated the DLL in C, and have a test version program
>also written in C that successfully calls and exersize the DLL.  However,
>when I attempt to link that into the Visual Basic program, I get an error
>49 "Bad DLL Calling Convention".  

>This error comes out -after- the DLL has successfully completed running and
>returned.  This seems to indicate that I might have the function type
>incorrectly defined (I have it defined as int in the C version and as Long
>in the Basic version.  

>I've used the convention
>    extern "C" __declspec( dllexport ) FunctionID  (char *Img_File, char
>*Cmp_File, int Threshold, int Importance, int Left, int Top, int Right, int
>Bottom)

>as the method to define the DLL routine interfaces, but I have also tried
>using WINAPI, FAR Pascal, and other combinations of things all with
>differing degrees of effectiveness with the C version of the calling
>program, but all failures with the Basic version.

>Is there something else I need to do to get this to work correctly with
>Visual Basic?

I had the same problem.  This is how I implement the .CPP file to
create a DLL.  I'm attaching an example DLL and corresponding VB
file..  I'm only including the code for the FontTest and LineTest
functions in C; it shows you how to pass an hDC to a DLL function
and then use it as one.

It's not fancy or high-faluten', but it'll do the job (and a lot
quicker than VB would! damn!)

LineTest draws a bunch-o' lines to the window;
FontTest draws rotated text to a window at a specific spot..

Modify it to do your own bidding!

// CHRIS
// Cosmic Computers, Inc.

In SOMEFILE.DLL:

#include <windows.h>
#include <ole2.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

// Declaration decoration!
#define DLLAPI          __declspec(dllexport)                  

// Examples of Declarations
DLLAPI BSTR _stdcall cml_UCase (BSTR);
DLLAPI short int _stdcall cml_OnlyDigits(BSTR);
DLLAPI BOOL _stdcall cml_strcmp(BSTR, BSTR);            
DLLAPI UINT _stdcall cml_sizeof(int);
DLLAPI void _stdcall cml_clipboundary(long int, long int, long int,
long int);
DLLAPI void _stdcall cml_clipShadow();
DLLAPI void _stdcall cml_clipFromShadow();
DLLAPI int _stdcall cml_clipsegment(long int *, long int *,     long
int *,  long int *);

DLLAPI void _stdcall cml_LineTest (long int, long int, long int, long
int, long int);
DLLAPI void _stdcall cml_FontTest(long, long, long, int);

//.================================================================
//
// Test function for drawing into a device context.  Units are Pixels,
// not twips!
//

DLLAPI void _stdcall cml_LineTest (long int p_hDC, long int ulc_x,
long int ulc_y, long int lrc_x, long int lrc_y, long int nShift)
{
        HDC hDC;
        long int dx, dy;
        long int k;

        hDC = (HDC) p_hDC;
        dx = labs(lrc_x - ulc_x);
        dy = labs(lrc_y - ulc_y);

        for (k=0; k < dx; k += nShift)
        {
                MoveToEx(hDC, ulc_x + k, ulc_y, NULL);
                LineTo(hDC, lrc_x - k, lrc_y);
        }

        for (k=0; k < dy; k += nShift)
        {
                MoveToEx(hDC, ulc_x, ulc_y + k, NULL);
                LineTo(hDC, lrc_x, lrc_y - k);
        }

        return;

Quote:
}

//.================================================================
// Coordinates are Pixel coord, not Twips!
// Draws a string in the center of window, at different angles.
DLLAPI void _stdcall cml_FontTest(long p_hdc, long cntr_x, long
cntr_y, int angle)
{
        HDC hDC;
        HFONT hfnt, hfntPrev;
        LPSTR lpszRotate = "Chicks dig it.";

        hDC = (HDC) p_hdc;

        // Allocate memory for LOGFONT structure
        PLOGFONT plf = (PLOGFONT) LocalAlloc(LPTR, sizeof(LOGFONT));

        // Specify font typeface name and weight
        lstrcpy(plf->lfFaceName,"Courier New");
        plf->lfWeight = FW_NORMAL;

        // Set background mode to transparent for the text output
operation
        // SetBkMode(hDC, TRANSPARENT);

        for(angle=0;angle < 3600; angle += 450)
        {
                plf->lfEscapement = angle;
                hfnt = CreateFontIndirect(plf);
                hfntPrev = SelectObject(hDC, hfnt);
                TextOut(hDC, cntr_x, cntr_y, lpszRotate,
lstrlen(lpszRotate));
                SelectObject(hDC, hfntPrev);
                DeleteObject(hfnt);
        }

        // SetBkMode(hDC, OPAQUE);
        LocalFree((LOCALHANDLE) plf);

Quote:
}

In SOMEFILE.BAS:

Public Declare Function cml_UCase Lib "QMAP32.DLL" (ByVal str As
String) As String

Public Declare Function cml_OnlyDigits Lib "QMAP32.DLL" (ByVal str As
String) As Integer

Public Declare Function cml_strcmp Lib "QMAP32.DLL" (ByVal str0 As
String, ByVal str1 As String) As Integer

Public Declare Function cml_sizeof Lib "QMAP32.DLL" (ByVal cType As
Integer) As Long

Public Declare Sub cml_clipboundary Lib "QMAP32.DLL" _
    (ByVal x_long As Long, ByVal x_lat As Long, ByVal y_long As Long,
ByVal y_lat As Long)

Public Declare Function cml_clipsegment Lib "QMAP32.DLL" (x_long As
Long, x_lat As Long, y_long As Long, y_lat As Long) As Integer

Public Declare Sub cml_clipShadow Lib "QMAP32.DLL" ()
Public Declare Sub cml_clipFromShadow Lib "QMAP32.DLL" ()

Public Declare Function cml_dsegs Lib "QMAP32.DLL" (SegData As Long)
As Long

Public Declare Function cml_dist2seg Lib "QMAP32.DLL" _
    (ByVal px As Long, ByVal py As Long, ByVal s_x1 As Long, ByVal
s_y1 As Long, ByVal s_x2 As Long, ByVal s_y2 As Long) As Double

Public Declare Sub cml_LineTest Lib "QMAP32.DLL" _
    (ByVal hDC As Long, ByVal ulc_x As Long, ByVal ulc_y As Long,
ByVal lrc_x As Long, ByVal lrc_y As Long, ByVal nStep As Long)

Public Declare Sub cml_FontTest Lib "QMAP32.DLL" _
    (ByVal hDC As Long, ByVal cntr_x As Long, ByVal cntr_y As Long,
ByVal angle As Integer)



Sat, 22 May 1999 03:00:00 GMT  
 Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0

Try taking a look at VB4DLL.txt.

It has allot of info on how VB's calling conventions.

Thanks,
Brandon



Sat, 22 May 1999 03:00:00 GMT  
 Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0

Patrick,

We also need to see your VB4 definition for this function.  I would declare
it in VB4 as follows...

declare FunctionID lib "libname.dll" (ByVal Img_File As String,
                ByVal Cmp_File As String,
                Threshold As Long,
                Left As Long,
                Top As Long,
                Right As Long,
                Bottom As Long) As Long

Note that you haven't defined a return type for the function.  I think C++
will default to an int return which equates to a Long in VB4-speak.

--
Paul Mitchell
British Gas Plc.



Quote:


> >I've used the convention
> >       extern "C" __declspec( dllexport ) FunctionID  (char *Img_File, char
> >*Cmp_File, int Threshold, int Importance, int Left, int Top, int Right,
int
> >Bottom)



Sun, 23 May 1999 03:00:00 GMT  
 Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0

The answer is sadly undocumented in the VB help and elsewhere.

A Win32 DLL created with VC4 uses the stdcall calling convention and NOT the
PASCAL calling convention. This means that the name in the dll is not "fred"

You _can_ call it from VB by aliasing it and declaring the function as


as long) as long

replacing nn by the real size of the arglist in bytes in hex, but this is
horrible.

The (totally undocumented) real answer is;

add a .DEF file to your VC++ project, with nothing except an EXPORTS section.
Yes, I know, .DEF files are EXPLICITLY declared as redundant under Win32, but
they aren't. If you define

EXPORTS
        fred

then VC++ 4.x will export the function with both a stdcall and a pascal stub
so that VC, VB and VBA can all call it. This makes the DLL totally transparent
to external apps.

Mark

ps this took me about two months to determine, despite calls to MS "hotline"
support. So why *is* life like{*filter*} upside down in a bucket of hyena offal?

pps does someone want to add this to the FAQ (please....)



Tue, 25 May 1999 03:00:00 GMT  
 Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0

Thanks for your reply, Mark, to the newsgroup postings.

I've had the same problem of a  Bad DLL Calling Convention, Error 49
on RETURNING to VB4.0 from a function (with parameters) in a DLL. I
tried the
addition to the .DEF file that you suggested but I still get the same
error.

One point that I've noticed is that I only get this problem when running
my VB
calling application in debug mode within the vb project. If I make an
EXE and
run this then the function returns fine.

Does anyone have any further comments/advice? I'm using VB4.0 and
VC++4.0.

A second query which might or might not be related:

Is it necessary to export the function which is exported to VB with a
__stdcall specifier.
Is there some kind of stack maintenance issue?
I tried this but I could not manage to declare the function properly
within VB.

I'd appreciate any help which anyone might be able to give.

Quote:

> The answer is sadly undocumented in the VB help and elsewhere.

> A Win32 DLL created with VC4 uses the stdcall calling convention and NOT the
> PASCAL calling convention. This means that the name in the dll is not "fred"

> You _can_ call it from VB by aliasing it and declaring the function as


> as long) as long

> replacing nn by the real size of the arglist in bytes in hex, but this is
> horrible.

> The (totally undocumented) real answer is;

> add a .DEF file to your VC++ project, with nothing except an EXPORTS section.
> Yes, I know, .DEF files are EXPLICITLY declared as redundant under Win32, but
> they aren't. If you define

> EXPORTS
>         fred

> then VC++ 4.x will export the function with both a stdcall and a pascal stub
> so that VC, VB and VBA can all call it. This makes the DLL totally transparent
> to external apps.

> Mark

> ps this took me about two months to determine, despite calls to MS "hotline"
> support. So why *is* life like{*filter*} upside down in a bucket of hyena offal?

> pps does someone want to add this to the FAQ (please....)



Sat, 05 Jun 1999 03:00:00 GMT  
 Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0

Ian,
I'm using VC++4.0 and VB4 like you, and I encountered the same problem.
I messed around with my DLL until it worked, both in debug and runtime
mode, I don't know the cause of this error though (like Mark, I did not
find any helpful documentation).  Here is how I do things, I remember
reading about this somewhere in the online help.  I hope this will help
you some.

BTW did you use the AppWizard to make your DLL?

        Ronald

Function protoype:  (HRESULT is just a long)
        EXTERN "C" HRESULT Zap(DWORD handle, char *winname);

Compiler settings:
        Changed C/C++/Code generation/Calling convention to __stdcall

In the .DEF file:
        EXPORTS
        Zap

In VB:
        Declare Function Zap Lib "lody.dll" (ByVal handle As Long, ByVal
window As String) As Long

Quote:

> I've had the same problem of a  Bad DLL Calling Convention, Error 49
> on RETURNING to VB4.0 from a function (with parameters) in a DLL. I
> tried the
> addition to the .DEF file that you suggested but I still get the same
> error.

> One point that I've noticed is that I only get this problem when running
> my VB
> calling application in debug mode within the vb project. If I make an
> EXE and
> run this then the function returns fine.

> Does anyone have any further comments/advice? I'm using VB4.0 and
> VC++4.0.

> A second query which might or might not be related:

> Is it necessary to export the function which is exported to VB with a
> __stdcall specifier.
> Is there some kind of stack maintenance issue?
> I tried this but I could not manage to declare the function properly
> within VB.

> I'd appreciate any help which anyone might be able to give.



Sun, 06 Jun 1999 03:00:00 GMT  
 Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0

I just looked at these issues and found a reference to a text file
VB4DLL.TXT in a Knowledge Base article. I did a Find on my system and found
it installed in my VB4 directory. Amazing that it was right on my nose.
It's a long article but very detailed. The best that I have seen. It
includes sample code. By the way, I decided after looking into it that I
could get by and stayed w/ VB. Good luck.



Mon, 07 Jun 1999 03:00:00 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Visual Basic 4.0 usage of DLLs written in Visual C++ 4.0

2. FS: Mastering Microsoft Visual Basic 4.0 and Visual C++ 4.0 CD-ROMs

3. VB 4.0 calling a Visual C++ 4.0 DLL

4. [Fwd: Visual Basic 5.0 to Visual C++ 4.0]

5. Scaling Printer Device Context between Visual Basic 4.0 and Visual C++ Problem

6. visual basic 4.0 call to borland c++ 5.0 dll

7. C++ DLL in Visual Basic 4.0

8. C++ DLL in Visual Basic 4.0

9. How to write Visual C++ DLL's and call them from Visual Basic

10. VB 4.0 calling Visual C++ 4.0 problem.

11. VB 4.0 calling Visual C++ 4.0 problem.

12. Visual Basic 4.0 Memory Usage

 

 
Powered by phpBB® Forum Software