Open hxbb00 opened 1 year ago
Hey, those parser bindings are generated by running the ParserGen
tool: https://github.com/mono/CppSharp/blob/main/src/CppParser/ParserGen/ParserGen.cs
You need to extend the parser generation setup in that file to add the triple you want to generate for.
You may also need this zip: https://github.com/mono/CppSharp/releases/download/CppSharp/headers.zip
Are you running CppSharp on an ARM64 system itself or trying to cross-generate?
I have almost finished the ARM64 support work, but there is a problem, I don't know whether it is a bug in the running time, can you help me to analyze the reason, here the pseudocode:
// DEBUG: class DLL_API StructWithPrivateFields
// DEBUG: {
// DEBUG: public:
// DEBUG: StructWithPrivateFields(int simplePrivateField, Foo complexPrivateField);
// DEBUG: int getSimplePrivateField();
// DEBUG: Foo getComplexPrivateField(); // ======the problem is here
// DEBUG: protected:
// DEBUG: int protectedField;
// DEBUG: private:
// DEBUG: int simplePrivateField;
// DEBUG: Foo complexPrivateField;
// DEBUG: }
When the function return value is a structure, the p/invoke function signature looks like this under the x86_64:
[SuppressUnmanagedCodeSecurity, DllImport("ConsoleApplicationARM"
, EntryPoint = "_ZN23StructWithPrivateFields22getComplexPrivateFieldEv", CallingConvention = __CallingConvention.Cdecl)]
internal static extern void GetComplexPrivateField_1(__IntPtr @return, __IntPtr __instance);
Pass the return value store address before(Linux) or after(MSVC) 'this' parameter(View bindings code ),But under the Arm64 architecture, it doesn't work,
I was checking and Clang uses the generic Itanium ABI for AArch64: https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/ItaniumCXXABI.cpp#L517
So I would expect the bindings should look exactly the same as on Linux x64 for these indirect returns.
I would try a simple example to trigger this in C++, look at the LLVM IR emitted by Clang to make sure it's what I expect, then try to P/Invoke it manually with a simple C# example. That should clear things up a bit.
I was checking and Clang uses the generic Itanium ABI for AArch64: https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/ItaniumCXXABI.cpp#L517
So I would expect the bindings should look exactly the same as on Linux x64 for these indirect returns.
I would try a simple example to trigger this in C++, look at the LLVM IR emitted by Clang to make sure it's what I expect, then try to P/Invoke it manually with a simple C# example. That should clear things up a bit.
I also think so at first, but it seems that the result is not so. Looking forward to your verification result
struct Foo
{
int A;
int P1;
int P2;
int P3;
int P4;
};
Foo getComplexPrivateField() { return Foo(); }
int main()
{
return getComplexPrivateField().A;
}
ARM64 LLVM IR:
%struct.Foo = type { i32, i32, i32, i32, i32 }
define dso_local void @_Z22getComplexPrivateFieldv(ptr noalias sret(%struct.Foo) align 4 %0) #0 !dbg !10 {
call void @llvm.memset.p0.i64(ptr align 4 %0, i8 0, i64 20, i1 false), !dbg !23
ret void, !dbg !24
}
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
define dso_local noundef i32 @main() #2 !dbg !25 {
%1 = alloca i32, align 4
%2 = alloca %struct.Foo, align 4
store i32 0, ptr %1, align 4
call void @_Z22getComplexPrivateFieldv(ptr sret(%struct.Foo) align 4 %2), !dbg !28
%3 = getelementptr inbounds %struct.Foo, ptr %2, i32 0, i32 0, !dbg !29
%4 = load i32, ptr %3, align 4, !dbg !29
ret i32 %4, !dbg !30
}
x86_64 LLVM IR:
%struct.Foo = type { i32, i32, i32, i32, i32 }
define dso_local void @_Z22getComplexPrivateFieldv(ptr noalias sret(%struct.Foo) align 4 %0) #0 !dbg !8 {
call void @llvm.memset.p0.i64(ptr align 4 %0, i8 0, i64 20, i1 false), !dbg !21
ret void, !dbg !22
}
declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg) #1
define dso_local noundef i32 @main() #2 !dbg !23 {
%1 = alloca i32, align 4
%2 = alloca %struct.Foo, align 4
store i32 0, ptr %1, align 4
call void @_Z22getComplexPrivateFieldv(ptr sret(%struct.Foo) align 4 %2), !dbg !26
%3 = getelementptr inbounds %struct.Foo, ptr %2, i32 0, i32 0, !dbg !27
%4 = load i32, ptr %3, align 4, !dbg !27
ret i32 %4, !dbg !28
}
As predicted, ABI looks the same, @_Z22getComplexPrivateFieldv(ptr sret(%struct.Foo) align 4 %2)
signature looks the same, and sret
parameter as expected.
Reproducable in: https://godbolt.org/z/qcqjsK4PM
Note: I simplified the code to the bare mininum, but with a this
member function it's the same: https://godbolt.org/z/7Trjfq4qr
Is it possible to have a problem with the p/invoke stub
Is it possible to have a problem with the p/invoke stub
If you want more help, you need to put more information in your responses. Or send a PR with your changes so I can take a look.
ConsoleApplicationARMTest.zip I'm sorry, here my sample code, i run it on my arm64 machine, The results are as follows:
Hi @tritao !Did you reproduce the problem?or do you need any more information from me
What about ARM64EC for Windows 11 on ARM?
What about ARM64EC for Windows 11 on ARM?
This is not supported currently, not even sure if Clang already supports this one.
I am trying to build CppSharp for arm64, but i do not know how to generate bindings(CppSharp/src/CppParser/Bindings/CSharp/aarch64-linux-gnu-cxx11abi), can anyone help me?