Solved

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

Posted on 2000-04-17
42
336 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
  • 23
  • 19
42 Comments
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
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
Comment Utility
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
Comment Utility
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
 

Author Comment

by:raymondwee
Comment Utility
Adjusted points from 60 to 100
0
 

Author Comment

by:raymondwee
Comment Utility
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
Comment Utility
no problem, have fun.
0
 

Author Comment

by:raymondwee
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
ok - what does depends.exe or quickview say the export is?

0
 
LVL 3

Expert Comment

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

regards,
Mike.

0
 

Author Comment

by:raymondwee
Comment Utility
It says:
Ordinal = 1(0x0001)
Hint = 0x0000
Function = Test
Entry Point = 0x00001014
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

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

Expert Comment

by:MDarling
Comment Utility
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
Comment Utility
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
Comment Utility
check your mail - i got it working pretty quickly.

did you mean to create an MFC regular DLL?

0
 

Author Comment

by:raymondwee
Comment Utility
Adjusted points from 100 to 120
0
 

Author Comment

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

Expert Comment

by:MDarling
Comment Utility
gonna have to try myself in BC5

i'll get back to you.

regards,
Mike.
0
 

Author Comment

by:raymondwee
Comment Utility
Thanks.
0
 
LVL 3

Expert Comment

by:MDarling
Comment Utility
check your mail.
0
 

Author Comment

by:raymondwee
Comment Utility
Adjusted points from 120 to 140
0
 

Author Comment

by:raymondwee
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
static? why if you want a dll?

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

Expert Comment

by:MDarling
Comment Utility
whats the current situation?

0
 

Author Comment

by:raymondwee
Comment Utility
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
Comment Utility
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 140 total points
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Thanks a lot.
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

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

743 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

16 Experts available now in Live!

Get 1:1 Help Now