Dj_Fx8
asked on
Help with first DLL
Hi
I have tried to create a DLL, so I Cereated MyDll using VS6 MFC AppWizard (dll) type Regular DLL using shared MFC DLL
Now I want my DLL to contain this function
int fnTest(Cstring string)
{
return string.GetLength();
}
Where and what do I need to do next??
I have tried to create a DLL, so I Cereated MyDll using VS6 MFC AppWizard (dll) type Regular DLL using shared MFC DLL
Now I want my DLL to contain this function
int fnTest(Cstring string)
{
return string.GetLength();
}
Where and what do I need to do next??
ASKER
>>>>#infdef TEST_DLL
Is that a typo and should be
#ifdef TEST_DLL
But now I'm getting the following error when I compile
D:\PROGRAMING\MyDll\MyDll. cpp(67) : warning C4273: 'fnTest' : inconsistent dll linkage. dllexport assumed.
Is that a typo and should be
#ifdef TEST_DLL
But now I'm getting the following error when I compile
D:\PROGRAMING\MyDll\MyDll.
>>>>#infdef TEST_DLL
>>Is that a typo and should be
>>#ifdef TEST_DLL
No.
>>Is that a typo and should be
>>#ifdef TEST_DLL
No.
Ooops, yes, it should be
#ifndef TEST_DLL
#define DYNLINK __declspec(dllimport)
#else
#define DYNLINK __declspec(dllexport)
#endif
#ifndef TEST_DLL
#define DYNLINK __declspec(dllimport)
#else
#define DYNLINK __declspec(dllexport)
#endif
ASKER
Ok I've got the DLL to compile now and have created a Test App to test my dll function, but it won't compile. Now I have included the MyDll.lib in my test app as follows
#ifdef _DEBUG
#pragma comment(lib, "D:\\Programing\\MyDll\\De bug\\MyDll .lib")
#else
#pragma comment(lib, "D:\\Programing\\MyDll\\Re lease\\MyD ll.lib")
#endif
#include "D:\\Programing\\MyDll\\My Dll.h"
and copied the dll to the test app source folder.
D:\PROGRAMING\Test\TestDlg .cpp(124) : error C2065: 'fnTest' : undeclared identifier
#ifdef _DEBUG
#pragma comment(lib, "D:\\Programing\\MyDll\\De
#else
#pragma comment(lib, "D:\\Programing\\MyDll\\Re
#endif
#include "D:\\Programing\\MyDll\\My
and copied the dll to the test app source folder.
D:\PROGRAMING\Test\TestDlg
You also require the app to 'know' what the function fnTest is. That is you require
#include "InsertPathToHeaderForFnTe st"
in your app.
I use a generic 'export' header when I do a dll. That has all the #includes for header files of functions the dll will export so I only require this one header to be included with the app. Does that make sense?
#include "InsertPathToHeaderForFnTe
in your app.
I use a generic 'export' header when I do a dll. That has all the #includes for header files of functions the dll will export so I only require this one header to be included with the app. Does that make sense?
A couple of other points.
Is this dll going to be used with C based apps? (if yes you will also require extern "C" to prevent name mangling).
Is this dll going to be used with apps not coded in C/C++. (If yes you will need to change the calling convention - settings, C/C++ settings, code generation to __stdcall)
Is this dll going to be used with C based apps? (if yes you will also require extern "C" to prevent name mangling).
Is this dll going to be used with apps not coded in C/C++. (If yes you will need to change the calling convention - settings, C/C++ settings, code generation to __stdcall)
>>D:\PROGRAMING\Test\TestD lg.cpp(124 ) : error C2065: 'fnTest' : undeclared identifier
How are you using it?
How are you using it?
I think there is one minor mistake just
do the following in your dll project
press Alt + F7 to goto project settings
in c/c++ tab with category 'general'
add ,TEST_DLL to Preprocessor Definitions
or you can add following to
#define TEST_DLL in stdafx.h(if it is there or any header file that is included before test.h
//test.h
#ifndef TEST_DLL //here is mistake as TEST_DLL is not yet defined
#define DYNLINK __declspec(dllimport)
#pragma message("dllimport")
#else
#define DYNLINK __declspec(dllexport)
#pragma message("dllexport")
#endif
as you are defining TEST_DLL in dll project
when you compile see in output that "dllexport" is getting printed
Good luck
vijay
do the following in your dll project
press Alt + F7 to goto project settings
in c/c++ tab with category 'general'
add ,TEST_DLL to Preprocessor Definitions
or you can add following to
#define TEST_DLL in stdafx.h(if it is there or any header file that is included before test.h
//test.h
#ifndef TEST_DLL //here is mistake as TEST_DLL is not yet defined
#define DYNLINK __declspec(dllimport)
#pragma message("dllimport")
#else
#define DYNLINK __declspec(dllexport)
#pragma message("dllexport")
#endif
as you are defining TEST_DLL in dll project
when you compile see in output that "dllexport" is getting printed
Good luck
vijay
ASKER
vijay
>>>>>>#ifndef TEST_DLL //here is mistake as TEST_DLL is not yet defined
Does this not cover what you are saying
// test.cpp
#define TEST_DLL
#include <test.h>
Defining 'TEST_DLL' will make the compiler treat the function as 'exported', whereas an application that uses the header sees it as 'imported'.
jkr
>>>>>>How are you using it?
As follows in the CDialog::OnInitDialog();
int n = fnTest();
Andy
>>>>>>#include "InsertPathToHeaderForFnTe st"
I have the the header included
Still the same error msg.
Can I just run over what I have done in the DLL because I'm not sure if I have declaration and definition in the correct places
I created the dll as I said in my orginal post which in the class view gave me
MyDllClasses
CMyDllApp()
So I declared my function in MyDll.h, and defined it in MyDll.cpp
Is that ok
Now I have used a DLL Spyer and it shows 1 function in my dll
?fnTest@CMyDllApp@@QAEHXZ Mem Id No 268439557
If thats any help
>>>>>>#ifndef TEST_DLL //here is mistake as TEST_DLL is not yet defined
Does this not cover what you are saying
// test.cpp
#define TEST_DLL
#include <test.h>
Defining 'TEST_DLL' will make the compiler treat the function as 'exported', whereas an application that uses the header sees it as 'imported'.
jkr
>>>>>>How are you using it?
As follows in the CDialog::OnInitDialog();
int n = fnTest();
Andy
>>>>>>#include "InsertPathToHeaderForFnTe
I have the the header included
Still the same error msg.
Can I just run over what I have done in the DLL because I'm not sure if I have declaration and definition in the correct places
I created the dll as I said in my orginal post which in the class view gave me
MyDllClasses
CMyDllApp()
So I declared my function in MyDll.h, and defined it in MyDll.cpp
Is that ok
Now I have used a DLL Spyer and it shows 1 function in my dll
?fnTest@CMyDllApp@@QAEHXZ Mem Id No 268439557
If thats any help
>>>>>>How are you using it?
>>As follows in the CDialog::OnInitDialog();
>> int n = fnTest();
Hm, your exported function is/was
int fnTest(Cstring string)
{
return string.GetLength();
}
So, you should use it like
CString str("test");
int n = fnTest(str);
When you do not supply an argument, the function will fail to find the function.
>>As follows in the CDialog::OnInitDialog();
>> int n = fnTest();
Hm, your exported function is/was
int fnTest(Cstring string)
{
return string.GetLength();
}
So, you should use it like
CString str("test");
int n = fnTest(str);
When you do not supply an argument, the function will fail to find the function.
Thats a decorated name.
Just try this out
#ifndef TEST_DLL
#define DYNLINK extern "C" int __declspec(dllimport)
#else
#define DYNLINK extern "C" int __declspec(dllexport)
#endif
so the names aren't decorated. (I've just copied the define from an earlier post, hope no spelling mistakes).
NOTE I have also put the return type of function before the __declspec
Just try this out
#ifndef TEST_DLL
#define DYNLINK extern "C" int __declspec(dllimport)
#else
#define DYNLINK extern "C" int __declspec(dllexport)
#endif
so the names aren't decorated. (I've just copied the define from an earlier post, hope no spelling mistakes).
NOTE I have also put the return type of function before the __declspec
>> extern "C"
You think that's a good idea with a function that takes an object as the argument?
You think that's a good idea with a function that takes an object as the argument?
If it doesn't like the CString you may have to use
int FnTest(LPCTSTR pszSomeString)
{
return _tcslen(pszSomeString);
}
int FnTest(LPCTSTR pszSomeString)
{
return _tcslen(pszSomeString);
}
jkr.
I am trying to see if it works overall with a slightly different way of defining the function. It's obvious this is a test function, maybe a CString object isn't really required.
I am trying to see if it works overall with a slightly different way of defining the function. It's obvious this is a test function, maybe a CString object isn't really required.
>>If it doesn't like the CString
This is the MFC area :o)
This is the MFC area :o)
ASKER
Sorry jkr I had simplified the function when I was having problems, it simply is the following at the min
int fnTest()
{
return 50;
}
int fnTest()
{
return 50;
}
>>Sorry jkr I had simplified the function when I was having problems
Have you changed the header file also?
Have you changed the header file also?
ASKER
Ok I might be onto something
#ifdef _DEBUG
#pragma comment(lib, "D:\\Programing\\MyDll\\De bug\\MyDll .lib")
#else
#pragma comment(lib, "D:\\Programing\\MyDll\\Re lease\\MyD ll.lib")
#endif
When I changed to Release for my test app it just gave me the same error.... I don't have a Release version of the dll done yet, should I not have got an error saying the dll was missing ???
#ifdef _DEBUG
#pragma comment(lib, "D:\\Programing\\MyDll\\De
#else
#pragma comment(lib, "D:\\Programing\\MyDll\\Re
#endif
When I changed to Release for my test app it just gave me the same error.... I don't have a Release version of the dll done yet, should I not have got an error saying the dll was missing ???
ASKER
>>>Have you changed the header file also?
Yip
Yip
ASKER
Sorry I missed a few posts
I tried the extern "C"
This line #define DYNLINK extern "C" int __declspec(dllexport)
caused the following errors
Compiling...
MyDll.cpp
dllexport
d:\programing\mydll\mydll. h(38) : error C2059: syntax error : 'string'
d:\programing\mydll\mydll. h(38) : error C2238: unexpected token(s) preceding ';'
D:\PROGRAMING\MyDll\MyDll. cpp(66) : error C2039: 'fnTest' : is not a member of 'CMyDllApp'
mydll.h(38)
int DYNLINK fnTest();
mydll.cpp(66)
int CMyDllApp::fnTest()
>>NOTE I have also put the return type of function before the __declspec
What happens whent I add other functions with diferent return types
I tried the extern "C"
This line #define DYNLINK extern "C" int __declspec(dllexport)
caused the following errors
Compiling...
MyDll.cpp
dllexport
d:\programing\mydll\mydll.
d:\programing\mydll\mydll.
D:\PROGRAMING\MyDll\MyDll.
mydll.h(38)
int DYNLINK fnTest();
mydll.cpp(66)
int CMyDllApp::fnTest()
>>NOTE I have also put the return type of function before the __declspec
What happens whent I add other functions with diferent return types
As I put "#pragma message" so you can see it yourself that if exported part is included or import part, just check it out and let me know.
Because when I put your code in test program(dll) it shows me warning that it is getting function imported instead of exported (hence the error function not defined in test program using the dll)so I put it in project setting and it is working.
putting #define TEST_DLL in your main file will not affect test.h so better put it the place I told you to.
Vijay
Because when I put your code in test program(dll) it shows me warning that it is getting function imported instead of exported (hence the error function not defined in test program using the dll)so I put it in project setting and it is working.
putting #define TEST_DLL in your main file will not affect test.h so better put it the place I told you to.
Vijay
Edit the .def file of the dll and put in
EXPORTS
; Explicit exports can go here
FnTest
in theory not necessary but..
EXPORTS
; Explicit exports can go here
FnTest
in theory not necessary but..
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Hi Vijay
>>As I put "#pragma message" so you can see it yourself that if exported part is included or import part
I put them in as you said and when I compile the DLL I get dllexport, and dllimportwhen I compile the Test app
>>ok tell me one thing what is CMyDllApp?
VS wizard put it there when I created the project for making the DLL
>>I think we are making very simple concept confused for nothing.
Yes we are, as is often said, can't see the trees for looking at the forest. The whole problem has been because I had declared fnTest as a member of CMyDll class, I simplified it as you suggested and it worked.
I would like to thank all 3 of you for helping me out and no doubt I'll be calling again on your skills and knowledge again in the near future. I feel that vijay should get the points as it was his post that lead me to the discovery of my problem, but I also feel andy and jrk deserve points too, so I will put up a question titled Andy And Jrk, so if you guys post to it I see you get a little something for your effort here
Many may thanks to all
Steven
>>As I put "#pragma message" so you can see it yourself that if exported part is included or import part
I put them in as you said and when I compile the DLL I get dllexport, and dllimportwhen I compile the Test app
>>ok tell me one thing what is CMyDllApp?
VS wizard put it there when I created the project for making the DLL
>>I think we are making very simple concept confused for nothing.
Yes we are, as is often said, can't see the trees for looking at the forest. The whole problem has been because I had declared fnTest as a member of CMyDll class, I simplified it as you suggested and it worked.
I would like to thank all 3 of you for helping me out and no doubt I'll be calling again on your skills and knowledge again in the near future. I feel that vijay should get the points as it was his post that lead me to the discovery of my problem, but I also feel andy and jrk deserve points too, so I will put up a question titled Andy And Jrk, so if you guys post to it I see you get a little something for your effort here
Many may thanks to all
Steven
No thanks for not honoring our efforts :-(
Will keep that in mind when deciding whether to post to your next Q or not.
Will keep that in mind when deciding whether to post to your next Q or not.
ASKER
jkr
>>No thanks for not honoring our efforts :-(
>>Will keep that in mind when deciding whether to post to your next Q or not.
PLEASE re-read my last post, you and andy will be honored
>>No thanks for not honoring our efforts :-(
>>Will keep that in mind when deciding whether to post to your next Q or not.
PLEASE re-read my last post, you and andy will be honored
*ARGH* - sorry, maybe I should not post anywhere when I really am p***ed from doing household chores the whole day. My apologies....
ASKER
Oh don't worry about it, I understand where your coming from, I just felt 500pts between the 3 of you's wasn't enough
Any way thank all of you?
Jkr it is good gesture from you that u realize immediately.
Any way I think we are here to share our knowledge, the knowledge we haven't born with but learn from someone else so it is our duty to keep this chain alive. See I think points are just for keep our ego high and keep us motivated so we should take it positively
Vijay
Jkr it is good gesture from you that u realize immediately.
Any way I think we are here to share our knowledge, the knowledge we haven't born with but learn from someone else so it is our duty to keep this chain alive. See I think points are just for keep our ego high and keep us motivated so we should take it positively
Vijay
You need to create a header file that applications that want to use the function in the DLL can include. Furthermore, you have to tell these apps that this function is imported from a DLL and tell the compiler linker to export this function from your DLL. This is done like
// test.h
#infdef TEST_DLL
#define DYNLINK __declspec(dllimport)
#else
#define DYNLINK __declspec(dllexport)
#endif
int DYNLINK fnTest(Cstring string);
Now, when building your DLL, all you have to do is
// test.cpp
#define TEST_DLL
#include <test.h>
Defining 'TEST_DLL' will make the compiler treat the function as 'exported', whereas an application that uses the header sees it as 'imported'.