Problem with function call in DLL (C)

Asked

Viewed 90 times

0

I’m having trouble executing a code that uses a function of a DLL, which has a pointer as argument, according to the prototype:

DLLIMPORT void add_std_func(object list)

Follow the macro definitions DLLIMPORT:

#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif

and kind object:

typedef char *string;
/*...*/
typedef void *pointer
/*...*/
typedef struct str_Intern_Object    Intern_Object, *object;
/*...*/
typedef struct str_Class *Class;

struct str_Class{
    const string name;
    const Class super;
    const size_t size;
    void (* ctor)(object, pointer);
    void (* dtor)(object);
};

struct str_Intern_Object{
    pointer data;
    Class class_pointer;
};

The problem is that if the function add_std_func is defined outside the DLL (in the project itself or in a static library), the code works normally; but, when it is in the DLL, the code causes a segmentation failure when accessing the parameter list. The DLL is added via argument to the compiler link (GCC). Does anyone know why this is happening?

  • 1

    A DLL is a dynamic library (Dynamically Linked Library). Why are you trying to turn on a DLL statically? The normal is to call Loadlibrary within the program. Loadlibrary give the place and name of the DLL you should add. If not added, the program cannot find the function.

  • In this case, the DLL is only an independent part of the code, but it must be present, being that only add_std_func and another function for callback registration are directly called by the main code. The idea is only to be able to update the DLL without having to recompile the rest of the project.

  • So you don’t want static link. You’re calling LoadLibrary and GetProcAddress before calling add_std_func?

  • The DLL is added to Linker during compilation, so it is loaded when the application is initialized (generating an error message when not found). The point is that the DLL is found and the function add_std_func is executed, but there is a segmentation failure when the function tries to access the parameter, which does not happen if it is in a static library.

  • I don’t know a way to connect a DLL statically. You must have a 'header' at build time that declares the functions that the DLL provides, but the link happens when running with Loadlibrary and Getprocaddress.

  • There is a header where the function add_std_func is declared. The DLL, in this case, functions as a library, but is loaded at runtime rather than compilation, as in the case of static libraries. In that case, there is no need to use LoadLibrary and GetProcAddress and I wouldn’t want to use them because I want to keep the code as portable as possible.

  • What the code looks like where you’re accessing list?

  • This code is a bit extensive and has dependencies, but I’ll leave the link to the project on github here.

Show 3 more comments

1 answer

0

How you are doing in C as it is in the question title and tag. Question I answered read, different from C++ works like this:

/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>

DLLIMPORT void HelloWorldC()
{
    MessageBox(0,"Olá mundo de uma DLL em C!\n","Hi",MB_ICONINFORMATION);
}

DLLIMPORT int AddC(int a, int b)
{
    return a+b;
}

DLLIMPORT int SubC(int a, int b)
{
    return a-b;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
    switch(fdwReason)
    {
        case DLL_PROCESS_ATTACH:
        {
            break;
        }
        case DLL_PROCESS_DETACH:
        {
            break;
        }
        case DLL_THREAD_ATTACH:
        {
            break;
        }
        case DLL_THREAD_DETACH:
        {
            break;
        }
    }
    
    /* Return TRUE on success, FALSE on failure */
    return TRUE;
}

Just adding some functions and we have the example of dllmain.c. The similarity is that it has the header include and the WINAPI function (Look at the link above) the difference that in the header and in this file has to put the dllexport.

#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
#define DLLIMPORT __declspec(dllexport)
#else
#define DLLIMPORT __declspec(dllimport)
#endif

DLLIMPORT void HelloWorldC();
DLLIMPORT int AddC(int a, int b);
DLLIMPORT int SubC(int a, int b);

#endif

This is also where the dllexport and can put in the: __declspec tipo nome or tipo __declspec nome. When compiling receives the dll and the . lib or . a, read the question I answered in a matter of including lib (if you have doubt) and then create a method header:

#ifndef C_H
#define C_H

    #define CDLL __declspec(dllimport)

    extern "C"
    {
        CDLL void HelloWorldC();
        CDLL int AddC(int a, int b);
        CDLL int SubC(int a, int b);
    }

#endif

Always at the time of dllimport place the items to be imported into extern "C" because it is important, if not put the compiler will give undefined reference use in C++ or C. To find out if your methods are being imported use Dependency Walker:

inserir a descrição da imagem aqui

In the end compiles and

inserir a descrição da imagem aqui

I did just function but this holds for these items of your question.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.