C
C#16mo ago
Bambosa

❔ P/Invoke x86 ASM

I have the following x86 assembly function:
section .text
global _add
_add:
; Arguments are in the registers: rcx and rdx

mov rax, rcx ; Move the first argument from rcx to rax
add rax, rdx ; Add the second argument from rdx to rax

ret ; Return
section .text
global _add
_add:
; Arguments are in the registers: rcx and rdx

mov rax, rcx ; Move the first argument from rcx to rax
add rax, rdx ; Add the second argument from rdx to rax

ret ; Return
I am compiling it into a win64 dll using NASM: nasm -f win64 maths.asm -o maths.dll The consuming project is set to 64 bit:
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Platforms>x64</Platforms>
</PropertyGroup>
Bindings in C#:
public static partial class Maths
{
[LibraryImport(Native.Maths)]
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvCdecl) })]
private static partial int add(int a, int b);

public static int Add(int a, int b) => add(a, b);
}
public static partial class Maths
{
[LibraryImport(Native.Maths)]
[UnmanagedCallConv(CallConvs = new[] { typeof(CallConvCdecl) })]
private static partial int add(int a, int b);

public static int Add(int a, int b) => add(a, b);
}
Unhandled exception. System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (0x8007000B)
at Native.Maths.add(Int32 a, Int32 b)
at Native.Maths.Add(Int32 a, Int32 b) in D:\Code\C#\AssemblyTest\Native\Maths.cs:line 12
at Program.<Main>$(String[] args) in D:\Code\C#\AssemblyTest\Managed\Program.cs:line 3
Unhandled exception. System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (0x8007000B)
at Native.Maths.add(Int32 a, Int32 b)
at Native.Maths.Add(Int32 a, Int32 b) in D:\Code\C#\AssemblyTest\Native\Maths.cs:line 12
at Program.<Main>$(String[] args) in D:\Code\C#\AssemblyTest\Managed\Program.cs:line 3
Does anyone have any idea what format this should be in for the runtime to accept, I assumed using the same platform architecture and CDECL calling conventions would be enough for this to work. Thanks
22 Replies
Petris
Petris16mo ago
The regs used here don't seem right?
Petris
Petris16mo ago
But even then, this should just return corrupt data, not throw an exception, @jkortech any ideas why this'd throw that?
Petris
Petris16mo ago
Oh wait, the bot quoted incorrectly in #allow-unsafe-blocks
Bambosa
BambosaOP16mo ago
yeah that was my bad, I had the asm from when I was trying to force everything 32 bit in the question so I switched it to the 64 bit regs basically ive tried every combination of 32/64 bit configs to get this to just run
Petris
Petris16mo ago
Does it also error out with DllImport instead of LibraryImport?
Bambosa
BambosaOP16mo ago
yeah exactly the same, I checked the output from the library import source generator and it uses the same DllImport anyways
Kouhai
Kouhai16mo ago
@Bambosa nasm only creates obj files Also you declared the asm function as _add but you import add they need to have a matching name
Petris
Petris16mo ago
yeah but that should still be a different exception then
Kouhai
Kouhai16mo ago
No? p/invoke anything other than a valid dll throws that
Bambosa
BambosaOP16mo ago
@Kouhai /人◕ ‿‿ ◕人\ I've used with and without _ and based on the cdecl calling convention you should indeed declare with _ and call without but happy to be wrong on that
Kouhai
Kouhai16mo ago
Still nasm creates obj files You need to link to a dll But if you export it as _add you have to p/invoke it as _add as well think
Bambosa
BambosaOP16mo ago
ok I will give it a go, I need a def file for the linker right?
Kouhai
Kouhai16mo ago
You might do something like lld-link maths.obj /dll /noentry /out:maths.dll /export:_add math.obj is the file generated by nasm so nasm -f win64 maths.asm -o maths.obj Here I'm using llvm's linker lld
Bambosa
BambosaOP16mo ago
ok cool, didn't have it so will comment once i've gotten everything linked thanks
Kouhai
Kouhai16mo ago
You could use vs c++ developer tools linker as well @Bambosa Which would be link instead of lld-link
Bambosa
BambosaOP16mo ago
I didn't have the C++ workload installed either, just the .NET stuff (new installation)
Kouhai
Kouhai16mo ago
Oh
Bambosa
BambosaOP16mo ago
just as easy to grab llvm from choco
Kouhai
Kouhai16mo ago
Yup
Bambosa
BambosaOP16mo ago
it worked! thank you 👍
Kouhai
Kouhai16mo ago
Np! <:MadoThumbsUp_MM:406514447973351444>
Accord
Accord16mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server