Menu

Help with creating dll?

deostroll
2007-12-14
2012-09-26
  • deostroll

    deostroll - 2007-12-14

    I get an error while making the DLL... I am posting the code and the compile log below. (The code is just newbie stuff...)

    ---mydll.h----

    ifndef SAMPLE_DLL_H_

    define SAMPLE_DLL_H_

    if BUILDING_DLL

    define DLLIMPORT __declspec (dllexport)

    else / Not BUILDING_DLL /

    define DLLIMPORT __declspec (dllimport)

    endif / Not BUILDING_DLL /

    class DLLIMPORT DllClass
    {
    public:
    DllClass();
    virtual ~DllClass(void);

    private:

    };

    extern "C" declspec (dllexport) stdcall void DisplayMessage();
    extern "C" declspec (dllexport) stdcall double Addition(double arg1, double arg2);

    endif / SAMPLE_DLL_H_ /

    ----mydllmain.cpp----

    include "mydll.h"

    include <windows.h>

    DllClass::DllClass()
    {

    }

    DllClass::~DllClass ()
    {

    }

    BOOL APIENTRY DllMain (HINSTANCE hInst / Library instance handle. / ,
    DWORD reason / Reason this function is being called. / ,
    LPVOID reserved / Not used. / )
    {
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    break;

      case DLL_PROCESS_DETACH:
        break;
    
      case DLL_THREAD_ATTACH:
        break;
    
      case DLL_THREAD_DETACH:
        break;
    }
    
    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
    

    }

    extern "C" declspec (dllexport) stdcall void DisplayMessage()
    {
    MessageBox(0,"This was called from within a dll","DLL Called!!!", MB_OK);
    }

    extern "C" declspec(dllexport) stdcall double Addition(double arg1, double arg2)
    {
    return arg1 + arg2;
    }

    ----compile log----

    Compiler: Default compiler
    Building Makefile: "D:\Dev-Cpp\Sample DLL\Makefile.win"
    Executing make...
    make.exe -f "D:\Dev-Cpp\Sample DLL\Makefile.win" all
    g++.exe -c mydllmain.cpp -o mydllmain.o -I"d:/Dev-Cpp/lib/gcc/mingw32/3.4.2/include" -I"d:/Dev-Cpp/include/c++/3.4.2/backward" -I"d:/Dev-Cpp/include/c++/3.4.2/mingw32" -I"d:/Dev-Cpp/include/c++/3.4.2" -I"d:/Dev-Cpp/include" -DBUILDING_DLL=1

    dllwrap.exe --output-def "libSample DLL.def" --driver-name c++ --implib "libSample DLL.a" mydllmain.o -L"d:/Dev-Cpp/lib" --no-export-all-symbols --add-stdcall-alias -o "Sample DLL.dll"

    dlltool: Unable to open object file: DLL.dll

    dllwrap.exe: no export definition file provided.
    Creating one, but that may not be what you want
    dllwrap.exe: dlltool exited with status 1

    make.exe: *** ["Sample] Error 1

    Execution terminated

     
    • cpns

      cpns - 2007-12-14

      You your project name and your project folder name contain a space character. That is what is screwing it up.

      The issue of spaces in paths is dealt with in the thread titled: "PLEASE READ BEFORE POSTING A QUESTION". I suggest you read it before posting another question. ;-)

       
      • cpns

        cpns - 2007-12-14

        ... Oh and putting your project in a sub-folder of the Dev-C++ installation is also a bad idea. There is some sort of weird bug that can in some circumstances prevent such projects from building. It is also a bad idea in general to 'pollute' an applications installation with your own data.

        Clifford

         
        • deostroll

          deostroll - 2007-12-14

          Ha, the space was the culprit. Thanx.

          One other doubt though. Why do I have a class defined by default whenever I start a dll project. If it is only meant to be a "class" how can I create an object of its kind and use in my program?

           
    • Fred Harris

      Fred Harris - 2007-12-20

      I'm curious about that too, deostroll. They probably want a new thread to answer/explain it though. Your thread interested me because I was thinking about learning to make/use dlls with Dev-C++, as I use them in VC++/embedded C++. I thought the declspec(dllexport) attribute specifiers were Microsoft specific, but I guess they're not. That's why I was wondering about making dlls with Dev-C++. Was thinking one might have to use module definition files, which I don't like much, but I guess not.

      Anyway, I tried your code and it worked for me too. It appears you can just delete all that class stuff you referred too, and it still works. Here's my code, first the dll then host app. The latter calls your function in the WM_CLOSE message. What I can't understand is why DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH are'nt getting called.

      To get it to work you have to add the library in Project >> Options

      //dllMain.cpp >> results in dllTest.dll (that's how I named my project)
      / Replace "dll.h" with the name of your header /

      include <windows.h>

      include <stdio.h>

      FILE* fp;

      extern "C" declspec (dllexport) stdcall void DisplayMessage()
      {
      MessageBox(0,"This was called from within a dll","DLL Called!!!", MB_OK);
      }

      extern "C" declspec(dllexport) stdcall double Addition(double arg1, double arg2)
      {
      return arg1 + arg2;
      }

      BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
      {
      switch(reason)
      {
      case DLL_PROCESS_ATTACH:
      fp=fopen("Output1.txt","w");
      fprintf(fp,"In DLL_PROCESS_ATTACH\n");
      break;
      case DLL_PROCESS_DETACH:
      fprintf(fp,"In DLL_PROCESS_DETACH\n");
      fclose(fp);
      break;
      }

      return TRUE;
      }

      //LoadDll is this project

      include <windows.h>

      include <stdio.h>

      typedef struct WindowsEventArguments //Package Window Procedure Parameters into structure
      {
      HWND hWnd; //Handle of Window
      WPARAM wParam; //Window Parameter
      LPARAM lParam; //Long Parameter
      HINSTANCE hIns; //Instance Handle (Resolves To Process Address)
      }WndEventArgs, *lpWndEventArgs;

      extern "C" declspec (dllimport) stdcall void DisplayMessage();
      extern "C" declspec (dllimport) stdcall double Addition(double arg1, double arg2);

      HINSTANCE hDll;
      FILE* fp;

      long fnWndProc_OnCreate(lpWndEventArgs Wea)
      {
      fp=fopen("Output.txt","w");
      Wea->hIns=((LPCREATESTRUCT)Wea->lParam)->hInstance;
      hDll=LoadLibrary("dllTest.dll");
      fprintf(fp,"hDll=%u\n",hDll);

      return 0;
      }

      long fnWndProc_OnClose(lpWndEventArgs Wea) //This function handles the WM_CLOSE message
      { //sent when the 'x' button is clicked.
      if(MessageBox(Wea->hWnd,"Do You Wish To Exit This App?","Exit Check?",MB_YESNO)==IDYES)
      {
      BOOL blnFree=FALSE;
      DisplayMessage();
      fprintf(fp,"Addition(1.5,1.6)=%f\n",Addition(1.5,1.6));
      blnFree=FreeLibrary(hDll);
      fprintf(fp,"blnFree=%u\n",blnFree);
      fclose(fp);
      DestroyWindow(Wea->hWnd);
      PostQuitMessage(WM_QUIT);
      }

      return 0;
      }

      long __stdcall fnWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) //This is the all important Window
      { //Procedure. Note that in WinMain()
      static WndEventArgs wea; //the WNDCLASSEX variable wc has a
      //field lpfnWndProc. This is pro-
      switch (msg) //nounced long pointer to Window
      { //Procedure. Below you can see where
      case WM_CREATE: //this variable was set to the
      wea.hWnd=hwnd, wea.wParam=wParam, wea.lParam=lParam; //address of this function. All
      return fnWndProc_OnCreate(&wea); //mouse, keyboard, COM, etc., inputs
      case WM_CLOSE: //destined for this program Windows
      wea.hWnd=hwnd, wea.wParam=wParam, wea.lParam=lParam; //will package up into a message
      return fnWndProc_OnClose(&wea); //packet consisting of the four
      } //parameters to this function and
      //and it will come blowing through
      return DefWindowProc(hwnd,msg,wParam,lParam); //here at blinding speed.
      }

      int __stdcall WinMain(HINSTANCE hIns,HINSTANCE hPrevIns,LPSTR lpszArgument,int iShow)
      { //The program starts in WinMain(). The WNDCLASSEX structure variable
      char szClassName[]="Form1"; //wc is filled out with general characteristics of a window. Then
      WNDCLASSEX wc; //the class is RegisteredClassEx()'ed. Directly after that a
      MSG messages; //CreateWindow() call instantiates an instance of the class. Then
      HWND hWnd; //the program drops into a message processing loop in which any messages
      //destined for this program are DispatchMessage()'ed to the fnWndProc().
      wc.lpszClassName=szClassName; wc.lpfnWndProc=fnWndProc;
      wc.cbSize=sizeof (WNDCLASSEX); wc.style=CS_DBLCLKS;
      wc.hIcon=LoadIcon(NULL,IDI_APPLICATION); wc.hInstance=hIns;
      wc.hIconSm=LoadIcon(NULL, IDI_APPLICATION); wc.hCursor=LoadCursor(NULL,IDC_ARROW);
      wc.hbrBackground=(HBRUSH)COLOR_BACKGROUND; wc.cbWndExtra=0;
      wc.lpszMenuName=NULL; wc.cbClsExtra=0;
      RegisterClassEx(&wc);
      hWnd=CreateWindow(szClassName,"Form1",WS_OVERLAPPEDWINDOW,200,100,400,350,HWND_DESKTOP,0,hIns,0);
      ShowWindow(hWnd,iShow);
      while(GetMessage(&messages,NULL,0,0))
      {
      TranslateMessage(&messages);
      DispatchMessage(&messages);
      }

      return messages.wParam;
      }

       
      • deostroll

        deostroll - 2007-12-21

        For all I know what I am doing below can be alleged as slander:

        To answer the question: why classes are there?...
        It is probably there bcuz
        a) for modularizing things inside the dll(?)
        b) or if we brought the dll in the project like a header file we could probably use the class (Implicit linking...check http://www.codeguru.com/cpp/cpp/cpp_mfc/tutorials/article.php/c9855/

        But what I am really interested to know is that if we brought the dll into the program dynamically how do we make use of the class which lies inside?

        -- deostroll

         
        • cpns

          cpns - 2007-12-21

          Same as anything else you would use in a DLL - a declaration in an associated header, link the generated export (.a) library.

           
          • deostroll

            deostroll - 2007-12-22

            Does this mean if we are trying to link at runtime we will not be able to use the classes inside the dll?
            - deostroll

             
            • cpns

              cpns - 2007-12-22

              I've never tried, but it seems I know how to use Google! ;-)

              http://www.codeguru.com/Cpp/W-P/dll/importexportissues/article.php/c123

              CodeGear (formerly Borland development tools) appear to make it easy with CreateClassInstance()and CreateClassObject() functions, ( http://dn.codegear.com/article/20165 ) but these are not standard Win32 API function as far as I am aware, and not available in Dev-C++. You could of course create them using information in the first link.

              Clifford

               
    • cpns

      cpns - 2007-12-20

      __declspec is merely a macro defined in windef.h in terms of the GNU attribute keyword for function attributes.

      The code in the template is there for no other reason than as a starting point. You get different code depending upon whether you select C or C++ as the project language. You can modify the template code by editing the appropriate files in the Templates folder.

      Note that if you implement a C++ interface (i.e. compile as C++ and do not use extern "C"), the resulting DLL is unlikely to be compatible with other compilers since there is no standard convention for C++'s 'name mangling'.

      Fred, this is the second time you have mentions "embedded C++" but you appear to be using it in an entirely different way to that which I understand it (as an embedded systems engineer of so 18 years experience). There is a (somewhat obsolete) subset of C++ for embedded systems known as EC++, and C++ itself can be used in embedded systems in any case, but you mention "embedded C++" in relation to Windows API calls and DLLs. I am guessing that you are referring to WinCE perhaps? But the term 'embedded' has broader meaning, so it would be more usual to refer to the target to avoid any confusion - only the tiniest minority or embedded systems code is targeted at the WinCE platform.

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.