Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling C function from Raku that was compiled in C++ on Windows, Why is it not working?

Tags:

windows

dll

raku

I have this code in 64bit dll on Windows

#define TEMPLATENEST_API __declspec(dllexport)

extern  "C"  TEMPLATENEST_API  void templatenest_init(void** object);

 void templatenest_init(void** object)
{
    //TemmplNest
    *object =(void*) new TemplateNestClass();

}

In raku,

sub templatenest_init(Pointer is rw) is native(dl) { * }


 my Pointer  $class_pointer;

 templatenest_init($class_pointer);
 templatenest_init($class_pointer)

However, after this line, $class_pointer was 0. Somehow the value of a the class pointer does not arrive in Raku. I checked in a Debugger that *object was set to non zero value.

Signature of the exported function
2 1 00025621 templatenest_init = @ILT+5660(templatenest_init)

Minimal example: Use Microsoft VIsual studio 2019 compile as dll library 64 bit

raku:

use v6;
use Data::Dump;
use NativeCall; 

#constant dl = 'D:\m\cpp\TemplateNest\template-nest-rakudl\TemplateNestDll.dll';

constant dl = 'D:\m\cpp\TemplateNest\x64\Debug\DllMinitest.dll';



sub get_dll_name()
{
     if $*VM.osname eq 'linux' {
        return 'templatenest';
     }
     else
{
      return dl;
}

}
sub templatenest_init(Pointer is rw) is native(get_dll_name) { * }

my Pointer $class_pointer;

  templatenest_init($class_pointer);
   say "{$class_pointer.Int}";

# it prints 0.

export.cpp:
#define TEMPLATENEST_API __declspec(dllexport)

class TemplateNestClass {



};

extern  "C"  TEMPLATENEST_API  void templatenest_init(void** object);

void templatenest_init(void** object)
{
    //TemmplNest
    *object = (void*) new TemplateNestClass();

}



dllmain:
// dllmain.cpp : Defines the entry point for the DLL application.


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
like image 565
Aftershock Avatar asked Nov 01 '25 17:11

Aftershock


1 Answers

A work around seems to work.

extern  "C"  TEMPLATENEST_API  void templatenest_init(__int64 * object);

sub templatenest_init(int64 is rw ) is native(get_dll_name) { * }

my int64 $class_pointer;

templatenest_init($class_pointer);

Actual answer: The pointer needs to be initialised like this: my Pointer $class_pointer = Pointer.new();

All Pointer stuff needs to be new-ed. Another example: my Pointer[Str] $html = Pointer[Str].new();

like image 134
Aftershock Avatar answered Nov 04 '25 07:11

Aftershock



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!