Solved

Help with first DLL

Posted on 2004-04-22
30
319 Views
Last Modified: 2013-11-20
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??




0
Comment
Question by:Dj_Fx8
  • 10
  • 10
  • 6
  • +1
30 Comments
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>Where and what do I need to do next??

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'.
0
 

Author Comment

by:Dj_Fx8
Comment Utility
>>>>#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.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>>>#infdef TEST_DLL
>>Is that a typo and should be
>>#ifdef TEST_DLL

No.
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Ooops, yes, it should be

#ifndef TEST_DLL
#define DYNLINK __declspec(dllimport)
#else
#define DYNLINK __declspec(dllexport)
#endif

0
 

Author Comment

by:Dj_Fx8
Comment Utility
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\\Debug\\MyDll.lib")
#else
#pragma comment(lib, "D:\\Programing\\MyDll\\Release\\MyDll.lib")
#endif

#include "D:\\Programing\\MyDll\\MyDll.h"

and copied the dll to the test app source folder.

D:\PROGRAMING\Test\TestDlg.cpp(124) : error C2065: 'fnTest' : undeclared identifier
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
You also require the app to 'know' what the function fnTest is.  That is you require

#include "InsertPathToHeaderForFnTest"

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?
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
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)
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>D:\PROGRAMING\Test\TestDlg.cpp(124) : error C2065: 'fnTest' : undeclared identifier

How are you using it?
0
 
LVL 7

Expert Comment

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

0
 

Author Comment

by:Dj_Fx8
Comment Utility
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 "InsertPathToHeaderForFnTest"

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
0
 
LVL 86

Expert Comment

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

0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
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
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>> extern "C"  

You think that's a good idea with a function that takes an object as the argument?
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
If it doesn't like the CString you may have to use

int FnTest(LPCTSTR pszSomeString)
{
return _tcslen(pszSomeString);
}
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
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.
0
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!

 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>If it doesn't like the CString

This is the MFC area :o)
0
 

Author Comment

by:Dj_Fx8
Comment Utility
Sorry jkr I had simplified the function when I was having problems, it simply is the following at the min
int fnTest()
{
   return 50;
}
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
>>Sorry jkr I had simplified the function when I was having problems

Have you changed the header file also?
0
 

Author Comment

by:Dj_Fx8
Comment Utility
Ok I might be onto something

#ifdef _DEBUG
#pragma comment(lib, "D:\\Programing\\MyDll\\Debug\\MyDll.lib")
#else
#pragma comment(lib, "D:\\Programing\\MyDll\\Release\\MyDll.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 ???

0
 

Author Comment

by:Dj_Fx8
Comment Utility
>>>Have you changed the header file also?

Yip
0
 

Author Comment

by:Dj_Fx8
Comment Utility
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
0
 
LVL 7

Expert Comment

by:vijay_visana
Comment Utility
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
0
 
LVL 44

Expert Comment

by:AndyAinscow
Comment Utility
Edit the .def file of the dll and put in

EXPORTS
    ; Explicit exports can go here
      FnTest


in theory not necessary but..
0
 
LVL 7

Accepted Solution

by:
vijay_visana earned 500 total points
Comment Utility
sorry I haven't seen  your last post.

ok tell me one thing what  is CMyDllApp? are you using some class in your dll and exporting member function.
confused because in your post following things are contradicting

>>mydll.h(38)
>>int DYNLINK fnTest();

>>mydll.cpp(66)
>>int CMyDllApp::fnTest()

If it is for test purpose do not make thing complecated do not put your exported function in any class.

What I have tested is very simple

// TEST2.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "test2.h"
//exported function
int  MyFunction(int k)
      {
            return k*k;
      }

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                               )
{
    return TRUE;
}

#pragma once
/////////////////////////////////////////////////////////
//test2.h

#ifndef TEST_DLL
#define DYNLINK __declspec(dllimport)
#pragma  message("dllimport")
#else
#define DYNLINK __declspec(dllexport)
#pragma  message("dllexport")
#endif
int DYNLINK MyFunction(int k);
///end test.h

////////////in programm that is using dll/////////////
copy your dll in folder of this program
add .lib and test2.h file directly to your project workspace
and call this function like

//////////////////////////////////////////////
//testdll.cpp
#include "test2.h"

int arg = 16;
printf(" Myfunction(%d) returns %d",arg,MyFunction(arg));


I think we are making very simple concept confused for nothing.


Vijay
0
 

Author Comment

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

0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
No thanks for not honoring our efforts :-(

Will keep that in mind when deciding whether to post to your next Q or not.
0
 

Author Comment

by:Dj_Fx8
Comment Utility
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
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
*ARGH* - sorry, maybe I should not post anywhere when I really am p***ed from doing household chores the whole day. My apologies....
0
 

Author Comment

by:Dj_Fx8
Comment Utility
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
0
 
LVL 7

Expert Comment

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

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
Complete beginner needs help making a cron job 9 104
java ^ examples 8 57
Path of Workbook 3 44
Thin secure Windows 10 5 46
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video discusses moving either the default database or any database to a new volume.

771 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

14 Experts available now in Live!

Get 1:1 Help Now