Solved

Help with first DLL

Posted on 2004-04-22
30
322 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
ID: 10893662
>>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
ID: 10893770
>>>>#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
ID: 10895369
>>>>#infdef TEST_DLL
>>Is that a typo and should be
>>#ifdef TEST_DLL

No.
0
 
LVL 86

Expert Comment

by:jkr
ID: 10895377
Ooops, yes, it should be

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

0
 

Author Comment

by:Dj_Fx8
ID: 10897016
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
ID: 10897176
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
ID: 10897203
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
ID: 10899896
>>D:\PROGRAMING\Test\TestDlg.cpp(124) : error C2065: 'fnTest' : undeclared identifier

How are you using it?
0
 
LVL 7

Expert Comment

by:vijay_visana
ID: 10900729
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
ID: 10902692
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
ID: 10902795
>>>>>>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
ID: 10902807
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
ID: 10902822
>> 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
ID: 10902833
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
ID: 10902867
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 86

Expert Comment

by:jkr
ID: 10902868
>>If it doesn't like the CString

This is the MFC area :o)
0
 

Author Comment

by:Dj_Fx8
ID: 10902872
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
ID: 10902906
>>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
ID: 10902943
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
ID: 10902959
>>>Have you changed the header file also?

Yip
0
 

Author Comment

by:Dj_Fx8
ID: 10904243
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
ID: 10906312
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
ID: 10906331
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
ID: 10906355
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
ID: 10909255
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
ID: 10909291
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
ID: 10909310
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
ID: 10909354
*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
ID: 10909385
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
ID: 10915557
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Different colored text in ComboBox without Subclassing 8 55
VB.NET how to use the Vertical ScrollBar 5 90
cat dog challenge 18 124
sum67 challenge 35 93
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Hints for the grid button.  Nested classes, templated collections.  Squash that darned bug! Continuing from the sixth article about sudoku.   Open the project in visual studio. First we will finish with the SUD_SETVALUE messa…
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.
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

920 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

17 Experts available now in Live!

Get 1:1 Help Now