tags:

views:

72

answers:

2

e.g. In a static library I had

  void function (void);

  function();

And function() existed in the main application.

But If I build it as a DLL the linker complains that the function is undefined on the DLL.

+3  A: 

Yes, but this is hackish.

In the dll :

typedef void(*funcPtr)(void);
// Declare a variable named "ptrFunction" which is a pointer to a function which takes void as parameter and returns void
funcPtr ptrFunction;
// setter for ptrFunction; will be called from the .exe
void DLL_EXPORT setFunction(funcPtr f){ptrFunction f;}
// You can now use function() through ptrFunction
foo(){
   ptrFunction();
}

and you call setFunction from the .exe.

void function(){
    // implementation here
}    
int main(){
    setFunction(&function);  // now the dll knows the adress of function()
    foo(); // calls foo() in dll, which calls function() in the .exe
    ....
}

Great, huh ? :/ You should probably refactor your code so that function() is in yet another DLL, but it depends.

Calvin1602
typedef line returns error: expected identifier or '(' before ')' token. on 15
Lela Dax
@Lela Dax: I think Calvin1602 meant `typedef void(*funcPtr)(void);`.
Charles Bailey
what is the '* f'?
Lela Dax
@Charles: Sorry, corrected. @Lela : f is the adress of the function() that is implemented in the .exe. See edit.
Calvin1602
+1 for a solution *and* advice to refactor.
Amardeep
I don't think that either `* f` is correct. In the parameter declaration `funcPtr` is already a pointer to a function so only `funcPtr f` is necessary. In the function body I assume that `ptrFunction * f;` should be `ptrFunction = f;`.In the .exe code `function` needs to return void.
Charles Bailey
correct, but I don't get the "In the .exe code function needs to return void"
Calvin1602
I meant that `function(){` isn't valid C (any more - it used to imply and implicit `int` return type), it should be `void function(){`.
Charles Bailey
+2  A: 

Yes you can but I would strongly recommend against it if you don't have to. It's fiddly and it feels like you need to sort out your dependencies better.

To do it, you have to use LIB.EXE to create an import library from the object files of one binary before you actually link it; use this import library to link other binary and create an import library for the other binary; finally use the other library's import library to link the original binary.

E.g.

exe.c:

#include <stdio.h>

void __declspec(dllimport) dllfn(void);

void __declspec(dllexport) exefn(void)
{
    puts("Hello, world!");
}

int main(void)
{
    dllfn();
    return 0;
}

Compiler with cl /c exe.c. exe.obj is created.

exe.def:

LIBRARY exe.exe

Create import library with lib /def:exe.def exe.obj. exe.lib and exe.exp are created.

dll.c:

void __declspec(dllimport) exefn(void);

void __declspec(dllexport) dllfn(void)
{
    exefn();
}

Compile with cl /c dll.c. dll.obj is created.

Link DLL with link /dll dll.obj exe.lib. dll.dll, dll.lib and dll.exp are created.

Link EXE with link exe.obj dll.lib. exe.exe is created. (exe.lib and exe.exp are also recreated.)

Run exe, note the Hello, world! output.

Charles Bailey