C++ interop, abstract struct problem

RSY rsy_881 at gmail.com
Mon Dec 28 15:42:26 UTC 2020


Hello

I try to use a C++ lib


So far so good, i managed to use that lib and get started

The problem however is this:

C++ API:
```
void preinit(IAllocator& allocator, bool load_renderdoc);
```


``IAllocator`` is an abstract struct, (a struct with virtual 
functions)

But the problem is D doesn't allow that, so apparently i need to 
use an abstract class and wrap it using: ``extern (C++, struct)``

The problem is, when passing the object to the function i get:

``dumix.obj : error LNK2019: unresolved external symbol "void 
__cdecl Lumix::gpu::preinit(struct Lumix::IAllocator *,bool)" 
(?preinit at gpu@Lumix@@YAXPEAUIAllocator at 2@_N at Z) referenced in 
function _Dmain ``


Wich is wrong, it is supposed to pass as a reference, i don't 
know why it is picky

Do you guys have an idea what i do wrong, or what i should do?

Thanks!

Here is the full code:


```
import std.stdio;
import core.thread;
import core.stdc.stdio;
import core.memory;

extern (C++, Lumix) @nogc nothrow
{

     extern (C++, os) @nogc nothrow
     {
         struct InitWindowArgs
         {
             enum Flags
             {
                 NO_DECORATION = 1 << 0,
                 NO_TASKBAR_ICON = 1 << 1
             }

             const(char)* name = "hello lumix";
             bool handle_file_drops = false;
             bool fullscreen = false;
             uint flags = 0;
             void* parent = null;
         }

         void* createWindow(const ref InitWindowArgs);
     }

     align(8) struct Mutex
     {
         ubyte[8] data;
     }


     extern (C++, struct) abstract class IAllocator
     {
         void* allocate(size_t n);
         void  deallocate(void* p);
         void* reallocate(void* ptr, size_t size);
         void* allocate_aligned(size_t size, size_t alignn);
         void  deallocate_aligned(void* ptr);
         void* reallocate_aligned(void* ptr, size_t size, size_t 
alignn);
     }

     extern (C++, struct) class DefaultAllocator : IAllocator
     {
         ubyte* m_small_allocations = null;
         void*[4] m_free_lists;
         uint m_page_count = 0;
         Mutex m_mutex;

         override void* allocate(size_t n);
         override void  deallocate(void* p);
         override void* reallocate(void* ptr, size_t size);
         override void* allocate_aligned(size_t size, size_t 
alignn);
         override void  deallocate_aligned(void* ptr);
         override void* reallocate_aligned(void* ptr, size_t size, 
size_t alignn);
     }

     extern (C++, gpu) @nogc nothrow
     {
         enum InitFlags : uint
         {
             NONE = 0,
             DEBUG_OUTPUT = 1 << 0,
             VSYNC = 1 << 1
         }

         // 1505C2 ?preinit at gpu@Lumix@@YAXAEAUIAllocator at 2@_N at Z
         void preinit(IAllocator allocator, bool load_renderdoc);
         bool init(void* window_handle, InitFlags flags);
         void* allocProgramHandle();
     }
}

void main()
{
     auto arg = InitWindowArgs();
     auto win = Lumix.os.createWindow(arg);

     IAllocator allocator = new DefaultAllocator();
     Lumix.gpu.preinit(allocator, false);
     Lumix.gpu.init(win, InitFlags.NONE);

     while (true)
     {
         Thread.sleep(usecs(1));
     }
}

```


More information about the Digitalmars-d-learn mailing list