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

x
?
Solved

Points for MDarling(Mike), with much apologies about grades

Posted on 2000-04-17
42
Medium Priority
?
398 Views
Last Modified: 2008-03-17
Sorry about the C grade..I didn't know abt the system here...Thus, I have posted this question again...

This is my latest header at the BC5 Main program:
extern "C" int __declspec(dllimport) _stdcall Test(char *name);

Still doesn't work
pls help
0
Comment
Question by:raymondwee
[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
  • 23
  • 19
42 Comments
 
LVL 3

Expert Comment

by:MDarling
ID: 2722678
typedef int (__stdcall tTestFunc)(char *);

void main()
{

  HANDLE hLib=LoadLibrary("MyLib.DLL");
  if(hLib)
  {
     FARPROC fProc=GetProcAddress(hLib,"Test");
     if(fProc)
     {
      // successfully got proc address
      tTestFunc* pFunc=(tTestFunc*)fProc;
      int n=pFunc("Hello");
     }
  }
}




if you are using GetProcAddress then you don't need to use __declspec(dllimport)

if you don't wish to use GetProcAddress then you can link in the .LIB from your DLL and use __declspec(dllimport)


re the grade - I don't mind getting a C if after consultation we can't reach the right solution.  But to get one without being asked for clarification or further help was a bit annoying.

If your not sure just ask.

Regards,
Mike.

P.S. you should delete the second of these 2 questions so you can get your points back.

0
 
LVL 3

Expert Comment

by:MDarling
ID: 2722697
r u going to need standard call mechanism?  if not then this is all you need...

main.cpp

#include <windows.h>

extern "C" {
typedef  int (tTestFunc)(char *);
}

void main()
{

  HINSTANCE hLib=LoadLibrary("dll.DLL");
  if(hLib)
  {
     FARPROC fProc=GetProcAddress(hLib,"Test");
     if(fProc)
     {
      // successfully got proc address
      tTestFunc* pFunc=(tTestFunc*)fProc;
      int n=pFunc("Hello");
     }
  }
}


dll.cpp

....

extern "C" int __declspec(dllexport) Test(char *s)
{
    MessageBox(NULL,"Hello","Test",MB_OK);
    return 100;
}



stdcall introduces name decoration

for example your function in stdcall would look like

_Test@4

this is because stdcall needs to know how many bytes in parameters are being passed so that it can tidy up the stack later.

a char * is 4 bytes.

regards,
Mike.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2722700
stdcall version...

main.cpp

#include <windows.h>

extern "C" {
typedef  int (__stdcall tTestFunc)(char *);
}

void main()
{

  HINSTANCE hLib=LoadLibrary("dll.DLL");
  if(hLib)
  {
     FARPROC fProc=GetProcAddress(hLib,"_Test@4");
     if(fProc)
     {
      // successfully got proc address
      tTestFunc* pFunc=(tTestFunc*)fProc;
      int n=pFunc("Hello");
     }
  }
}


dll.cpp

....

extern "C" int __declspec(dllexport) __stdcall Test(char *s)
{
    MessageBox(NULL,"Hello","Test",MB_OK);
    return 100;
}





0
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!

 

Author Comment

by:raymondwee
ID: 2722803
Adjusted points from 60 to 100
0
 

Author Comment

by:raymondwee
ID: 2722804
Thanks for all the suggestions.
I am not at my study station.
I will try that out tomolo.
Thanks a lot.
It is very kind of you...
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2722852
no problem, have fun.
0
 

Author Comment

by:raymondwee
ID: 2725026
Below is the main program.
I got an error on compilation.
It says: "Declaration Terminated Incorrectly" at
line stating :
extern "C"
{
typedef int (__stdcall pfunctest)(char *);
}

It should be syntax error but I can't figure out why.
Pld help.

Main Program:

#include <windows.h>
#include <string.h>
#include <stdio.h>

extern "C"
{
typedef int (__stdcall pfunctest)(char *);
}

int main(void)
{
   HANDLE hLib=LoadLibrary("test.dll");
   if(hLib)
   {
     FARPROC fProc = NULL;
     fProc = GetProcAddress(hLib,"test");
     if(fProc)
     {
     // successfully got proc address
         printf("OK");
         pfuncFindEmail* pFind=(pfunctest*)fProc;
         found = test(name);
     }
     else
          printf("NOT OK");
   }
   else
      printf("LIB PROB");
   return 1;
}
0
 

Author Comment

by:raymondwee
ID: 2725031
There are some minor errors after it get the Proc Address. Those are my mistakes.  I am aware of them.

My main concern is the "extern" declaration..

Thanks
0
 

Author Comment

by:raymondwee
ID: 2725039
There are some minor errors after it get the Proc Address. Those are my mistakes.  I am aware of them.

My main concern is the "extern" declaration..

Thanks
0
 

Author Comment

by:raymondwee
ID: 2725477
I have changed the VC6 dll(test.dll) header to:

#define DllExport _declspec(dllexport)

extern "C" int DllExport _stdcall Test(char *);

I have also changed the test.def to:

Export:
     Test

I have also added the "ifdef" to the BC5 main program, as shown below.
However, I could not get the proc address.
(fProc == NULL)
If I add the "__stdcall", it gives my compilation error.

How can I solve this?

#include <windows.h>
#include <string.h>
#include <stdio.h>

#ifdef __cplusplus
extern "C" {
#endif
typedef int (*pfuncTest)(char *);
#ifdef __cplusplus
}
#endif

int main(void)
{
   pfuncTest  pDone= NULL;
   int done = 0;
   HINSTANCE hLib=LoadLibrary("test.dll");
   if(hLib)
   {
     FARPROC fProc = NULL;
     fProc = GetProcAddress(hLib,"Test");
     pDone = (pfuncTest)fProc;
     if(fProc)
     {
        // successfully got proc address
         printf("OK");
         done = pDone("Hello");
         printf("\nDone = %d",done);
     }
     else
         printf("NOT OK");
   }
   else
         printf("LIB PROB");
   return 1;
}
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2725810
try _stdcall instead of __stdcall

your using BC5? - I don't have that at work.  Only at home - may take me a while to look at this.

also try putting a semi-colon after the braces for extern "C" - the Borland compiler might need that.

i presume your dll is compiling - if so did you put stdcall on?  use quickview or depends.exe in the VC++ tools to see what the function is exported as.

regards,
Mike.
0
 

Author Comment

by:raymondwee
ID: 2725908
I have tried everything that you have mentioned but it doesn't work with BC5.02

From the VC++ depends.exe, I can see that "Test" is exported, with ordinal = 1(0x001)
Entry Point = 0x0001019

I have added in the test.def:

Exports:
      Test

I believe this will force it to export "Test" instead of _Test@..

Is there anyway other than loadlibrary?

I have also tried dllexport and dllimport, but still doesn't work.





0
 
LVL 3

Expert Comment

by:MDarling
ID: 2725973
with depends you should be able to see what name it is exported as.

>> is there anyway other than loadlibrary?

sure - you could link in the lib and use

declspec(dllimport) in your main.cpp.

but you never answered the question - will you ever want to use this DLL from another language other than C++?

by the way, why

typedef int (*pfuncTest)(char *);

instead of

typedef int (pfuncTest)(char *);

????

also if you have __stdcall in one you need it in the other - for starters though don't use stdcall at all.

regards,
Mike.




0
 

Author Comment

by:raymondwee
ID: 2725976
I have tried everything that you have mentioned but it doesn't work with BC5.02

From the VC++ depends.exe, I can see that "Test" is exported, with ordinal = 1(0x001)
Entry Point = 0x0001019

I have added in the test.def:

Exports:
      Test

I believe this will force it to export "Test" instead of _Test@..

Is there anyway other than loadlibrary?

I have also tried dllexport and dllimport, but still doesn't work.





0
 

Author Comment

by:raymondwee
ID: 2726702
Below are muy latest program.
I have tried with VC6 using the Dll. It works fine.
but not with BC5 main using the Dll.
The problem is still the same: It cannot get the Proc Address.


My test.dll:
extern "C" int DllExport __stdcall Test(char *name)
{
      AfxMessageBox(name);
      return 100;
}

My main program(test.cpp)
 #include <windows.h>
 #include <string.h>
 #include <stdio.h>
 #define DllExport declspec(dllexport)
 #ifdef __cplusplus
  extern "C" {
 #endif
  typedef int (pfuncTest)(char *);
 #ifdef __cplusplus
 }
 #endif

 int main(void)
 {
       int done = 0;
       HINSTANCE hLib=LoadLibrary("Test.dll");
       if(hLib)
      {
          FARPROC fProc = NULL;
          fProc = GetProcAddress(hLib,"Test");
          if(fProc)
          {
                 // successfully got proc address
              printf("OK");
              printf("\nDone = %d",done);
           else
              printf("NOT OK");
       }  
       else
           printf("LIB PROB");
       
       return 1;
 }
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2726709
your using stdcall in your dll - remove it and try again.

look at the exports using depends.exe

you should either see "Test" or "_Test@4"  if it's the latter then you still have stdcall mechanism in yuour dll.

regards,
Mike.

0
 

Author Comment

by:raymondwee
ID: 2726790
I remove the stdcall at the dll.
But the result is "NOT OK".
Still can't get the proc add.
0
 

Author Comment

by:raymondwee
ID: 2726849
I remove the stdcall at the dll.
But the result is "NOT OK".
Still can't get the proc add.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2726886
ok - what does depends.exe or quickview say the export is?

0
 
LVL 3

Expert Comment

by:MDarling
ID: 2726934
can you mail me your source code and dll
at michael@mpdco.freeserve.co.uk?

regards,
Mike.

0
 

Author Comment

by:raymondwee
ID: 2726946
It says:
Ordinal = 1(0x0001)
Hint = 0x0000
Function = Test
Entry Point = 0x00001014
0
 

Author Comment

by:raymondwee
ID: 2726952
It says:
Ordinal = 1(0x0001)
Hint = 0x0000
Function = Test
Entry Point = 0x00001014
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2726967
and your definitely loading the correct dll - ie not an old one?

because if the function is "Test" then your code should work.

please paste your main.cpp again, or send me the lot to the address above.

thanks,
mike.
0
 

Author Comment

by:raymondwee
ID: 2727187
I have copied the latest test.dll to the appropriate directory before I recompile the main code.

I have emailed u my source code...

Thanks alot.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2727192
check your mail - i got it working pretty quickly.

did you mean to create an MFC regular DLL?

0
 

Author Comment

by:raymondwee
ID: 2727248
Adjusted points from 100 to 120
0
 

Author Comment

by:raymondwee
ID: 2727249
I have tried out.
Pls read your email.
But still a bit of problem
Thanks
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2727367
gonna have to try myself in BC5

i'll get back to you.

regards,
Mike.
0
 

Author Comment

by:raymondwee
ID: 2727373
Thanks.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2728226
check your mail.
0
 

Author Comment

by:raymondwee
ID: 2729268
Adjusted points from 120 to 140
0
 

Author Comment

by:raymondwee
ID: 2729269
Hi Micheal,
It works....Thanks a lot.
So it is without the extern "C". Since loadlibrary is used...
What if I want to use the import way instead of loadlibrary?

I tried using extern "C" and dllimport thing and add the test.lib to my project...but linking error...

0
 
LVL 3

Expert Comment

by:MDarling
ID: 2729842
the lib way huh?

you need to link in the .lib and declare the function the same as in your dll.


this is the usual way in Microsoft

extern "C" int __declspec(dllimport) Test(char *s);

not too sure what that is in BC though.
Could well be something like...

extern "C" int import Test(char *s);

regards,
Mike.
0
 

Author Comment

by:raymondwee
ID: 2730117
In my BC5 main program,
I tried with:
extern "C" int _import Test(char *);
then use
Done = Test("HEllo");
There is a linker error that is not documented in my BC5 error message.
It says:....\test.lib contains invalid OMF record, type 0x21

I have compiled my test.lib as a static library in VC++6.
 
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2730161
static? why if you want a dll?

Also, i belive microsoft will be producing a COFF record.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2733803
whats the current situation?

0
 

Author Comment

by:raymondwee
ID: 2734113
The other time the dll one works very well.
now, I need to try out the "static" way.
As in static linking using test.lib written in VC6 and have a main program in BC5.

I have tried the 1 which i wrote above but can't work.


sorry if i have confused u.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2734131
ok - i suspect the linking formats of the 2 compilers way well be different.

what i suspect is that

BC uses OMF
MSVC uses COFF

they aren't compatible.

If I'm right then a lib produced with one cannot be used by the other unless the lib is converted using a utility program.

regards,
Mike.
0
 
LVL 3

Accepted Solution

by:
MDarling earned 560 total points
ID: 2734173
after consulting a colleague he agrees that this is the case.  

there is a utility with microsoft C++ called editbin.exe which should to the convert job for you.

just run editbin with no options except the name of your lib and it will convert the BC5 OMF format LIB to COFF format suitable for VC++.

regards,
Mike.



0
 

Author Comment

by:raymondwee
ID: 2746534
Thanks for all your help...
Nearly forget to grade you...
Hope you can help with the BC5 Main program using static library from VC++.
Juz email me.
Once again, Thanks a lot.
0
 
LVL 3

Expert Comment

by:MDarling
ID: 2746806
No problem - I'll mail you tomorrow if I get the chance - little busy at the moment.

If you don't get anything from me then don't be afraid to mail me a reminder.

Cheers,
Mike.
0
 

Author Comment

by:raymondwee
ID: 2747049
Thanks a lot.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

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

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
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 clear a vector as well as how to detect empty vectors in C++.

721 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