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 <[email protected]>
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);
}