Search code examples
c++verilator

Using typedef void* within a .dll


I try to make a .dll from the Verialtor source code, since they've implemented this possibility.

They use a common handler typedef void* svScope to initialize scopes. The .dll uses this handle aswell. Now I'm able to create new functions using

__declspec(dllexport) svScope svGetScope( void );

Here's the header code svdpi.h

#ifndef INCLUDED_SVDPI
#define INCLUDED_SVDPI

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

__declspec(dllexport) typedef void* svScope;

__declspec(dllexport) svScope svGetScope( void );

#ifdef __cplusplus
}
#endif
#endif

And a simple implementation svdpi.cpp

#include "svdpi.h"

svScope svGetScope() {return 0;}

I've created the test file test.cpp

#include <stdlib.h>
#include <stdio.h>
#include "svdpi.h"

int main()
{
    svScope Scope = svGetScope();
}

I compiled the library and linked it. The compiler finds the library yet I get this error

g++ -o test.exe -s test.o -L. -lsvdpi

c:/mingw/bin/../lib/gcc/mingw32/9.2.0/../../../../mingw32/bin/ld.exe: test.o:test.cpp:(.text+0xf): undefined reference to `_imp__svGetScope' collect2.exe: error: ld returned 1 exit status


Solution

  • You need to use XXTERN on a function delcaration. You're not showing us any actual source code that contains functions that must be exported, but let's imagine this:

    svScope foo();
    

    This function will return a svScope, which is just a void *. If you want it to be exported you must mark it so with __declspec(export) (or, in your case XXTERN:

    XXTERN svScope foo();
    

    See Exporting from a DLL Using __declspec(dllexport).

    EDIT: After the question was edited.

    In your DLL you need:

    __declspec(dllexport) svScope foo();
    

    And in the application that uses the DLL you need:

    __declspec(dllimport) svScope foo();