By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,376 Members | 1,559 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,376 IT Pros & Developers. It's quick & easy.

pblm in making dll using vc++

P: 52
can anyone tell wats the error in following code...
when building it ,lots of error are there...unable to understand ..
header ..dt1.h

Expand|Select|Wrap|Line Numbers
  1. #ifndef INDLL_H
  2. #define INDLL_H
  3.  
  4. #ifdef EXPORTING_DLL
  5. extern __declspec(dllexport) string summ(string,string) ;
  6. #else
  7. extern __declspec(dllimport) string summ(string,string) ;
  8. #endif
  9.  
  10. #endif
dt1.cpp
Expand|Select|Wrap|Line Numbers
  1. #include<iostream>
  2. #include<string>
  3. #include "dt1.h"
  4. #define EXPORTING_DLL
  5. using namespace std;
  6.  
  7. string summ(string a,string b)
  8. {  string c=a.append(b);
  9.     return c;
  10. }
  11.  
May 31 '07 #1
Share this Question
Share on Google+
12 Replies


Banfa
Expert Mod 5K+
P: 8,916
Post the errors you are getting, also I am moving this post to a more appropriate forum.
May 31 '07 #2

weaknessforcats
Expert Mod 5K+
P: 9,197
One problem you have is that a dll is a C thing. In C function names have to be unique. They have to be unique in C++ too but the C++ function overloading lets you have many functions of the same name so long as the arguments are different. Therefore, the C++ compiler will decorate (mangle) the function name and its arguments into a unique name like PQAAX@YZ. That will be the name of the function in the dll. Not good.

You need to use extern "C" in your C++ code to turn off the mangler. You will lose C++ function overloading.

Or you might keep C++ function overloading and export the mangled name as something else by using a DEF file.

Here is a Visual C++ example.

Create a dll project. Then:

Expand|Select|Wrap|Line Numbers
  1. ;BEGIN ADLL.DEF FILE
  2. ;This DEF file is required becuase the argument to GetProcAddress()
  3. ;for the function is a C-string and it will never be equal to the
  4. ;C++ mangled name for the function
  5. ;This DEF file maps the mangled name to a name that can be used with GetProcAddress()
  6. ;Note also: Change project settings in Visual Studio to send the LINK this def file.
  7. ;Visual Studio.NET: Project Properties/Linker/Input/Module Definition File/...Path to the def file\Adll.def
  8. LIBRARY ADll 
  9. EXPORTS 
  10. ;Exported Name    C++ Mangled Name
  11. AreaOfSquare   =  ?AreaOfSquare@@YGHHH@Z
  12. DisplayFromDll =  ?DisplayFromDll@@YGXXZ
  13. ;END DEF FILE 
  14.  
The cpp file for the dll is:

Expand|Select|Wrap|Line Numbers
  1. void __stdcall DisplayFromDll()
  2. {
  3.     cout << "This function was called from ADLL.dll" << endl;
  4. }
  5.  
  6. int __stdcall AreaOfSquare (int len, int wid)
  7. {
  8.     return len * wid;
  9. }
  10.  
And you use by:

Expand|Select|Wrap|Line Numbers
  1. int main()
  2. {
  3.  
  4.  
  5.  
  6.     cout << "Calling functions from a dll" << endl;
  7.  
  8.     //First, load the dll into memory
  9.     HMODULE theDll = LoadLibrary("C:\\Scratch\\ClassDemos\\ADll\\Debug\\ADll.dll");
  10.     if (!theDll)
  11.     {
  12.         cout << "The dll failed to load" << endl;
  13.         return 1;
  14.     }
  15.  
  16.     //Second, get the address of the desried function from the dll
  17.     FARPROC addr = GetProcAddress(theDll, "DisplayFromDll");
  18.     if (!addr)
  19.     {
  20.  
  21.         //Look up the error in the system errors list
  22.         unsigned int what = GetLastError();
  23.         if (what == ERROR_PROC_NOT_FOUND)
  24.         {
  25.             cout << "Function not found in the dll" << endl;
  26.         }
  27.         else
  28.         {
  29.             cout << "Error: " << what << endl;
  30.         }
  31.         return 2;
  32.     }
  33.     cout << "The function has been located in the dll" << endl;
  34.     //Declare a function pointer that can accept the address of the function.
  35.     //You will need to know the function prototype to do this.
  36.     //Dll function prototypes should be provided by the vendor of the dll
  37.     void (__stdcall *DisplayFromDll)();
  38.     //Type-cast the address returned from GetProcAddress to the function pointer type
  39.     DisplayFromDll = reinterpret_cast<void (__stdcall *)()>  (addr);
  40.     //Now use the function pointer to call the function:
  41.     DisplayFromDll();
  42.  
  43.     //If you don't use a .def file in the dll, you must use the mangled name
  44.     //Second, get the address of the desried function from the dll
  45.     addr = GetProcAddress(theDll, "AreaOfSquare");
  46.     if (!addr)
  47.     {
  48.  
  49.         //Look up the error in the system errors list
  50.         unsigned int what = GetLastError();
  51.         if (what == ERROR_PROC_NOT_FOUND)
  52.         {
  53.             cout << "Function not found in the dll" << endl;
  54.         }
  55.         else
  56.         {
  57.             cout << "Error: " << what << endl;
  58.         }
  59.         return 2;
  60.     }
  61.  
  62.     cout << "The function has been located in the dll" << endl;
  63.     //Declare a function pointer that can accept the address of the function.
  64.     //You will need to know the function prototype to do this.
  65.     //Dll function prototypes should be provided by the vendor of the dll
  66.     int (__stdcall *AreaOfSquare)(int, int);
  67.     //Type-cast the address returned from GetProcAddress to the function pointer type
  68.     AreaOfSquare = reinterpret_cast<int (__stdcall*)(int,int)>  (addr);
  69.     //Now use the function pointer to call the function:
  70.     cout << "The area of a 6x8 square is " << AreaOfSquare(6,8) << endl;;
  71.  
  72.     //Finally, unload the dll from memory
  73.     FreeLibrary(theDll);
  74.  
  75.     return 0;
  76. }
  77.  
May 31 '07 #3

P: 52
the errors which m getting::
Expand|Select|Wrap|Line Numbers
  1. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.h(6) : error C2146: syntax error : missing ';' before identifier 'summ'
  2. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.h(6) : error C2501: 'summ' : missing storage-class or type specifiers
  3. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.h(6) : error C2078: too many initializers
  4. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2872: 'string' : ambiguous symbol
  5.         could be 'c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.h(6) : int string'
  6.         or       'c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xstring(1562) : std::string'
  7. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2146: syntax error : missing ';' before identifier 'summ'
  8. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2501: 'string' : missing storage-class or type specifiers
  9. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : warning C4273: 'string' : inconsistent dll linkage
  10. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2872: 'string' : ambiguous symbol
  11.         could be 'c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.h(6) : int string'
  12.         or       'c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xstring(1562) : std::string'
  13. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2872: 'string' : ambiguous symbol
  14.         could be 'c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.h(6) : int string'
  15.         or       'c:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\include\xstring(1562) : std::string'
  16. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2146: syntax error : missing ')' before identifier 'a'
  17. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2501: 'summ' : missing storage-class or type specifiers
  18. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2086: 'int summ' : redefinition
  19.         c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.h(6) : see declaration of 'summ'
  20. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(6) : error C2059: syntax error : ')'
  21. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(7) : error C2143: syntax error : missing ';' before '{'
  22. c:\Documents and Settings\mypc\My Documents\Visual Studio Projects\dt\dt\dt.cpp(7) : error C2447: '{' : missing function header (old-style formal list?)
  23.  

all these errors vanish when the dllimport statements in header file are removed...
Jun 1 '07 #4

P: 52
@weaknessforcats

but for the following code there is no error and it works fine...
dt.h
Expand|Select|Wrap|Line Numbers
  1.   #ifndef INDLL_H
  2.       #define INDLL_H
  3.       #ifdef EXPORTING_DLL
  4.       extern __declspec(dllexport) int summ(int,int) ;
  5.       #else
  6.       extern __declspec(dllimport) int summ(int,int) ;
  7.       #endif
  8.       #endif
  9.  
dt.cpp
Expand|Select|Wrap|Line Numbers
  1. #include<iostream>
  2.     #include<string>
  3.     #include "dt.h"
  4.     #define EXPORTING_DLL
  5.     using namespace std;
  6.     int summ(int a,int b)
  7.     {  int c=a+b;
  8.        return c;
  9.     }
  10.  
  11.  
Jun 1 '07 #5

Banfa
Expert Mod 5K+
P: 8,916
One problem you have is that a dll is a C thing.
I don't think that's true, I am reasonably sure you can put C++ functions (and classes) into a DLL if you want to.
Jun 1 '07 #6

P: 52
whats bothering me is that when i write a function involving int..its working fine but
when i write using string ..lots of error..
Jun 1 '07 #7

Banfa
Expert Mod 5K+
P: 8,916
Right sorry about the delay had to investigate so I could tell you the full story, your initial problem is compiling is that you have not included the string header.

This code compiles

DLL Header
Expand|Select|Wrap|Line Numbers
  1. #ifndef DLLTESTER_H_INCLUDED
  2. #define DLLTESTER_H_INCLUDED
  3.  
  4. #ifdef DLLTESTER_EXPORTS
  5. #define DLLTESTER_API __declspec(dllexport)
  6. #else
  7. #define DLLTESTER_API __declspec(dllimport)
  8. #endif
  9.  
  10. #include <string>
  11.  
  12. // This class is exported from the DLLTester.dll
  13. class DLLTESTER_API CDLLTester {
  14. public:
  15.     CDLLTester(void);
  16.     ~CDLLTester(void);
  17.     // TODO: add your methods here.
  18. };
  19.  
  20. DLLTESTER_API int fnDLLTesterInt(void);
  21.  
  22. // This is an example of an exported function.
  23. DLLTESTER_API std::string fnDLLTesterString(void);
  24.  
  25. DLLTESTER_API char *fnDLLTesterNewTest(void);
  26.  
  27. #endif  // ndef DLLTESTER_H_INCLUDED
  28.  
DLL Source file
Expand|Select|Wrap|Line Numbers
  1. // DLLTester.cpp : Defines the entry point for the DLL application.
  2. //
  3.  
  4. #include <iostream>
  5.  
  6. #include "stdafx.h"
  7. #include "DLLTester.h"
  8.  
  9. using namespace std;
  10.  
  11. BOOL APIENTRY DllMain( HANDLE hModule, 
  12.                        DWORD  ul_reason_for_call, 
  13.                        LPVOID lpReserved
  14.                      )
  15. {
  16.     switch (ul_reason_for_call)
  17.     {
  18.         case DLL_PROCESS_ATTACH:
  19.         case DLL_THREAD_ATTACH:
  20.         case DLL_THREAD_DETACH:
  21.         case DLL_PROCESS_DETACH:
  22.             break;
  23.     }
  24.     return TRUE;
  25. }
  26.  
  27.  
  28. // This is an example of an exported function.
  29. DLLTESTER_API int fnDLLTesterInt(void)
  30. {
  31.     return 42;
  32. }
  33.  
  34. // This is an example of an exported function.
  35. DLLTESTER_API string fnDLLTesterString(void)
  36. {
  37.     return "The meaning of Life, the Universe and Everything";
  38. }
  39.  
  40. // This is an example of an exported function.
  41. DLLTESTER_API char *fnDLLTesterNewTest(void)
  42. {
  43.     return new char[10];
  44. }
  45.  
  46.  
  47. // This is the constructor of a class that has been exported.
  48. // see DLLTester.h for the class definition
  49. CDLLTester::CDLLTester()
  50.     cout << "Constructed CDLLTester" << endl;
  51. }
  52.  
  53.  
  54. // This is the constructor of a class that has been exported.
  55. // see DLLTester.h for the class definition
  56. CDLLTester::~CDLLTester()
  57.     cout << "Destructed CDLLTester" << endl;
  58. }
  59.  
Program Source File
Expand|Select|Wrap|Line Numbers
  1. #include "DLLTester.h"
  2.  
  3. #include <iostream>
  4. #include <string>
  5.  
  6. using namespace std;
  7.  
  8.  
  9. int main(int argc, char **argp)
  10. {
  11.     CDLLTester class_in_dll;
  12.  
  13.     cout << fnDLLTesterString() << " : " << fnDLLTesterInt() << endl;
  14.  
  15.     return 0;
  16. }
  17.  
This compiles and looks like it should work, but it doesn't you get a run time error.

The problem is that the DLL (which is an application in it's own right) and the application use separate heaps. This means that when fnDLLTesterString() returns a temporary object is created that has a reference to the string in the DLL function that is also allocated on the heap. When the temporary object is no longer needed it is destructed and this includes deleting the memory used to hold the actual data, however we are in the application and the memory is on the DLLs heap this causes an error as the pointer is not a valid heap pointer in the application.

This is verifiable using the function fnDLLTesterNewTest() which just returns new'd data. If you try to delete it in the application you will get the same problem.

This can be solved by returning char * rather than string and copying the memory pointed to but you have to be sure you are returning a pointer to persistent memory

DLL Header file
Expand|Select|Wrap|Line Numbers
  1. #ifndef DLLTESTER_H_INCLUDED
  2. #define DLLTESTER_H_INCLUDED
  3.  
  4. #ifdef DLLTESTER_EXPORTS
  5. #define DLLTESTER_API __declspec(dllexport)
  6. #else
  7. #define DLLTESTER_API __declspec(dllimport)
  8. #endif
  9.  
  10. // This class is exported from the DLLTester.dll
  11. class DLLTESTER_API CDLLTester {
  12. public:
  13.     CDLLTester(void);
  14.     ~CDLLTester(void);
  15.     // TODO: add your methods here.
  16. };
  17.  
  18. DLLTESTER_API int fnDLLTesterInt(void);
  19.  
  20. // This is an example of an exported function.
  21. DLLTESTER_API char *fnDLLTesterString(void);
  22.  
  23. DLLTESTER_API char *fnDLLTesterNewTest(void);
  24.  
  25. #endif  // ndef DLLTESTER_H_INCLUDED
  26.  
DLL Source file snippet
Expand|Select|Wrap|Line Numbers
  1. // This is an example of an exported function.
  2. DLLTESTER_API char *fnDLLTesterString(void)
  3. {
  4.     return "The meaning of Life, the Universe and Everything";
  5. }
  6.  
Of course the problem here is having persistent data to return so a better method could be to have a function that takes a pointer to a buffer and a size which then fills in the provided buffer.


Because of the way the STL works, in that a lot of the operations can result in a memory allocation this means it is very inadvisable to try and share STL objects between an application and a DLL. The DLL can use STL objects internally and the application can use STL objects as well but they should not try to share them.
Jun 1 '07 #8

P: 52
well including <string>
doesnt have any effect..errors are still there...

char* works fine...but what if i want to use string only...
Jun 1 '07 #9

Banfa
Expert Mod 5K+
P: 8,916
char* works fine...but what if i want to use string only...
Please read my post, you can not pass a string back from a DLL.
Jun 1 '07 #10

P: 52
ok..thnks ..
can u suggest some sites where i can get info about dll..and understand the basics.
Jun 1 '07 #11

Banfa
Expert Mod 5K+
P: 8,916

P: 52
ya ..i already have gone thru many sites which google gives as result..but still didnt get a really good one..
Jun 1 '07 #13

Post your reply

Sign in to post your reply or Sign up for a free account.