Link to home
Start Free TrialLog in
Avatar of raymondwee
raymondwee

asked on

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

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
Avatar of MDarling
MDarling

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.

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.
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;
}





Avatar of raymondwee

ASKER

Adjusted points from 60 to 100
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...
no problem, have fun.
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;
}
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
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
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;
}
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.
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.





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.




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.





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;
 }
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.

I remove the stdcall at the dll.
But the result is "NOT OK".
Still can't get the proc add.
I remove the stdcall at the dll.
But the result is "NOT OK".
Still can't get the proc add.
ok - what does depends.exe or quickview say the export is?

can you mail me your source code and dll
at michael@mpdco.freeserve.co.uk?

regards,
Mike.

It says:
Ordinal = 1(0x0001)
Hint = 0x0000
Function = Test
Entry Point = 0x00001014
It says:
Ordinal = 1(0x0001)
Hint = 0x0000
Function = Test
Entry Point = 0x00001014
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.
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.
check your mail - i got it working pretty quickly.

did you mean to create an MFC regular DLL?

Adjusted points from 100 to 120
I have tried out.
Pls read your email.
But still a bit of problem
Thanks
gonna have to try myself in BC5

i'll get back to you.

regards,
Mike.
Thanks.
check your mail.
Adjusted points from 120 to 140
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...

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.
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.
 
static? why if you want a dll?

Also, i belive microsoft will be producing a COFF record.
whats the current situation?

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.
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.
ASKER CERTIFIED SOLUTION
Avatar of MDarling
MDarling

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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.
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.
Thanks a lot.