Solved

Basics for setting up a C++ DLL for VB

Posted on 1998-01-23
16
267 Views
Last Modified: 2012-05-04
I've been trying to call a C function from a VB project, but keep getting a run-time error '453': Can't find DLL entry point for <function> in <path>.

I've set up the VB side and called the Windows API MessageBeep() and it works great.  I think I'm just missing something in my function declaration or something else. I just need to know what are the essential tasks in making a function visible to a VB project. (i.e. declarations, return types, includes, etc.)
0
Comment
Question by:kodiak1
  • 8
  • 8
16 Comments
 

Author Comment

by:kodiak1
ID: 1178755
Edited text of question
0
 
LVL 22

Accepted Solution

by:
nietod earned 70 total points
ID: 1178756
answer coming.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1178757
Here is a sample VC C++ dll that exports a single function.  To export a finction you need to declare it with __declspec(dllexport), since that is ugly, I #define DllExp.  Since you will be exporting to an non C++ application you need to use the extern "C" directive to tell it not mangle the function name.  (You could use a #define to put the extern "c" in as well, I don't.)

#define DllExp __declspec(dllexport)

DllExp extern "C" int FunctionToExport(int i)
{
   return i + 1;
}

bool
WINAPI DllMain(HINSTANCE DLLHnd, // >> DLL module.                              ULONG     Rsn,    // Reason for calling fuction.                 LPVOID    Rsv)    // Reserved.                    {
   return true;
}

0
 
LVL 22

Expert Comment

by:nietod
ID: 1178758
Wow that came out really badly formatted!

here is the DllMain again.

bool
WINAPI DllMain(HINSTANCE DLLHnd,ULONG Rsn,LPVOID Rsv)
{
   return true;
}
0
 

Author Comment

by:kodiak1
ID: 1178759
Now I seen the declaration part before, however, I have no idea what the dllMain function is for.  I'm assuming that it is the entry part of the file I was missing before.  Is this needed in every DLL file? Could you give me some reasoning behind the DLLMAIN function?
0
 
LVL 22

Expert Comment

by:nietod
ID: 1178760
Every dll, just like every EXE, must have a an entry point.  The entry point is specified to the linker which records its location in the dll file, so the entry point could be called anything you want.  However, for convenience, Visual C treats any procedure with the name "DllMain" and the appropriate arguments as the entry point.  (Strictkly speaking it is not the entry point.  The VC run-tim libraries contain the entry point which then calls this procedure.)

This procedure is required for all Dll's.  Windows will call the procedure under 4 circumstances.  When the library is attached to a process, detached from a process, attached to a thread, detached from a thread.  The Rsn parameter indicates why the procedure is being called.  The bool return value is used only when attachiong to a process.  If the procedure returns false, it indicates the Dll could not initialize for some reason and windows will not continue to start up the EXE or DLL that uses the Dll.  

If you do not have to do any start-up/shut-down processing, you can leave the procedure blank, as I did in the example.
0
 

Author Comment

by:kodiak1
ID: 1178761
I'm sure I'm doing something really stupid, but I think I'm missing an include file or library.  It doesn't like the DllMain declaration The error I keep getting is:

error C2239: unexpected token 'identifier' following declaration of 'WINAPI'
 
  and also

error C2061: syntax error : identifier 'DllMain'

Do I use another name, is DllMain something you came up with?  Here's exactly what I have in .cpp the file.:

#define DllExp __declspec(dllexport)

DllExp extern "C" int Myfunc(int i)
{
        return i + 1;
}

bool WINAPI DllMain(HINSTANCE DLLHnd,ULONG Rsn,LPVOID Rsv)
{
return true;
}

Do I need a include to declare WINAPI as a keyword?  Thanks for al the extra effort.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1178762
you need to include the windows include files "windows.h".  I have to go.  hopefully this helps you.  I'll check in tomorrow morning.
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:kodiak1
ID: 1178763
I'm still having trouble seeing these functions in VB.  I have recently added the name to the .Def file and it finally worked, but it died once it was passed through the function.  Now I can't get it to work again.  Did it not unload the DLL correctly?  do I need to do something specific to keep it from doing that?  I think this is bigger than I thought to begin with.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1178764
I suspect the problem now is calling syntax, that is parameter format and/or order.  

The default C++ calling convention (__cdecl) is to place parameters on the stack in reverse order and the caller is responsible for removing the parameters after the function returns.  Return values are returned in EAX.  Does this match the VB calling convention and/or can you specify that this convention be used for a function.  

Vissual C also supports the pascal (__stdcall) calling convention.  In this case the function is responsible for cleaning up the stack.  

If this doesn't help, post some sample code.


0
 

Author Comment

by:kodiak1
ID: 1178765
BOOL WINAPI DllEntryPoint(HINSTANCE hinstDLL, DWORD fdwReason,
                 LPVOID lpReserved )
                 {
                     switch( fdwReason )
                     {
                     case DLL_PROCESS_ATTACH:
                     break;

                     case DLL_THREAD_ATTACH:
                     break;

                     case DLL_THREAD_DETACH:
                     break;

                     case DLL_PROCESS_DETACH:
                     break;
                     }
                     return FALSE;
                 }

__declspec( dllexport ) int WINAPI DateAndTime( int i )
{
      
      return i + 2;

}

The above is my C++ exported function.  I had it returning i + 1 and no matter what I passed in I got -3513 and now I get -3512.  On the VB side this is how I declared it:

Option Explicit

Declare Function DateAndTime Lib "Framer" (i As Integer) As Integer

the function name doesn't mean anything, I'm just trying to get stuff to work.  Its not crashing, but I'm not sure why its working? Or why its giving screwy numbers.  You'll have to tell me if you think its a VB problem.  I'm not sure now.  I had no trouble calling pre-compiled WINAPI functions before.  thanks
0
 

Author Comment

by:kodiak1
ID: 1178766
Finally got this to work thanks for your efforts.  I just changed the (i As Integer) As Integer to (ByVal i As Integer) As Integer and changed the declaration of the C to short instead of integer.  thanks for you help
0
 
LVL 22

Expert Comment

by:nietod
ID: 1178767
A short is only 16 bits.  Is that the right size?
0
 

Author Comment

by:kodiak1
ID: 1178768
I can change that as the data deems it necessary.  I just needed something to work.  I'm in a kind of demonstration phase and needed a working system.  I'll switch to longs if I need bigger numbers.  

I may have to implement array or string passing and I'm not too sure how I'll do that, but I'll worry about that bridge when I come, unless its a no brainer.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1178769
I understand that.  My question was does a VB integer correspond to a C++ short?  i.e. is a VB integer only 16 bits.  (I'm not looking for an answer, I just want to make sure that's a question you've asked yourself.)  
0
 

Author Comment

by:kodiak1
ID: 1178770
Sorry, I misunderstood.  I'm not sure, but from other materials I've read it seemed to suggest just that.  

   short = integer
   long = long
   double = double
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

758 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

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now