Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Basics for setting up a C++ DLL for VB

Posted on 1998-01-23
16
Medium Priority
?
281 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
[X]
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
  • 8
  • 8
16 Comments
 

Author Comment

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

Accepted Solution

by:
nietod earned 140 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
Independent Software Vendors: 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!

 
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
 

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

Independent Software Vendors: 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

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
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 goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

722 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