Hi,

In order to play with perl I wanted to do a gui. I decided to try to
bind qt libraries via nativecall[1]. Nativecall contains logic for g++
or msvc which tries to guess mangled name. I found that it does not work
that well for qt libraries. Especially on windows the actual symbols are
far from nativecall guess. So I decided I'll compile the shim library
exporting qt functionality into 'extern "C"' to make the symbols
predictable. Sadly I can't force nativecall to not mangle symbols at
all. I'm using the attached patch and in the perl itself

class QString is repr<CPPStruct> is QObject {
    has Pointer $.vtable;

        my sub qt_QString(Str) returns QString is native('./p6', v1) is
        mangled(False) { * };
...

Important is the 'is mangled(False)'.

Could something like this be included into nativecall?

[1] https://bitbucket.org/vlmarek/perl6-qt (beware, only proof of
concept)

Thank you
-- 
        Vlad
diff --git a/lib/NativeCall.pm6 b/lib/NativeCall.pm6
index 3fabbbb..ff378c1 100644
--- a/lib/NativeCall.pm6
+++ b/lib/NativeCall.pm6
@@ -180,15 +180,16 @@ sub type_code_for(Mu ::T) {
 }
 
 sub gen_native_symbol(Routine $r, :$cpp-name-mangler) {
-    if $r.package.REPR eq 'CPPStruct' {
-        $cpp-name-mangler($r, $r.?native_symbol // ($r.package.^name ~ '::' ~ 
$r.name))
-    }
-    elsif $r.?native_call_mangled {
+    if ! $r.?native_call_mangled {
+        # Native symbol or name is said to be already mangled
+        $r.?native_symbol // $r.name;
+    } elsif $r.package.REPR eq 'CPPStruct' {
+        # Mangle C++ classes
+        $cpp-name-mangler($r, $r.?native_symbol // ($r.package.^name ~ '::' ~ 
$r.name));
+    } else {
+        # Mangle C
         $cpp-name-mangler($r, $r.?native_symbol // $r.name)
     }
-    else {
-        $r.?native_symbol // $r.name
-    }
 }
 
 multi sub map_return_type(Mu $type) { Mu }
@@ -289,9 +290,17 @@ my role Native[Routine $r, $libname where 
Str|Callable|List] {
     has Pointer $!entry-point;
 
     method !setup() {
+        # Make sure that C++ methotds are treated as mangled (unless set 
otherwise)
+        if self.package.REPR eq 'CPPStruct' and not 
self.does(NativeCallMangled) {
+          self does NativeCallMangled[True];
+        }
+
         my $guessed_libname = guess_library_name($libname);
-        $!cpp-name-mangler  = %lib{$guessed_libname} //
-            (%lib{$guessed_libname} = guess-name-mangler($r, 
$guessed_libname));
+        if self.does(NativeCallMangled) and $r.?native_call_mangled {
+          # if needed, try to guess mangler
+          $!cpp-name-mangler  = %lib{$guessed_libname} //
+              (%lib{$guessed_libname} = guess-name-mangler($r, 
$guessed_libname));
+        }
         my Mu $arg_info := param_list_for($r.signature, $r);
         my $conv = self.?native_call_convention || '';
         nqp::buildnativecall(self,

commit 0f118259330184b4e06bdb025e8b416967efe8eb
Author: neuron <vlma...@volny.cz>
Date:   Wed Jul 6 07:37:58 2016 +0200

    Move role definitions before the setup method

diff --git a/lib/NativeCall.pm6 b/lib/NativeCall.pm6
index db7a2cf..3fabbbb 100644
--- a/lib/NativeCall.pm6
+++ b/lib/NativeCall.pm6
@@ -18,6 +18,22 @@ my constant CArray        is export(:types, :DEFAULT) = 
NativeCall::Types::CArra
 my constant Pointer       is export(:types, :DEFAULT) = 
NativeCall::Types::Pointer;
 my constant OpaquePointer is export(:types, :DEFAULT) = 
NativeCall::Types::Pointer;
 
+
+# Role for carrying extra calling convention information.
+my role NativeCallingConvention[$name] {
+    method native_call_convention() { $name };
+}
+
+# Role for carrying extra string encoding information.
+my role NativeCallEncoded[$name] {
+    method native_call_encoded() { $name };
+}
+
+my role NativeCallMangled[$name] {
+    method native_call_mangled() { $name }
+}
+
+
 # Throwaway type just to get us some way to get at the NativeCall
 # representation.
 my class native_callsite is repr('NativeCall') { }
@@ -304,20 +320,6 @@ my role Native[Routine $r, $libname where 
Str|Callable|List] {
     }
 }
 
-# Role for carrying extra calling convention information.
-my role NativeCallingConvention[$name] {
-    method native_call_convention() { $name };
-}
-
-# Role for carrying extra string encoding information.
-my role NativeCallEncoded[$name] {
-    method native_call_encoded() { $name };
-}
-
-my role NativeCallMangled[$name] {
-    method native_call_mangled() { $name }
-}
-
 multi sub postcircumfix:<[ ]>(CArray:D \array, $pos) is export(:DEFAULT, 
:types) {
     $pos ~~ Iterable ?? $pos.map: { array.AT-POS($_) } !! array.AT-POS($pos);
 }

Reply via email to