I have this simple rust function.
#[no_mangle]
pub extern fn add_numbers(number1: i32, number2: i32) -> i32 {
println!("Hello from rust!");
number1 + number2
}
which is compiled to dll with
[lib]
name = "my_lib"
crate-type = ["dylib"]
I tried to use the dll from a C# console app (full framework), and it worked. However, when I am trying to do the same for a C# netcore console app, I am getting System.BadImageFormatException
. This is what I have in the C# side
using System;
using System.Runtime.InteropServices;
namespace my_core_console
{
class Program
{
[DllImport(@"my_lib.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern Int32 add_numbers(Int32 number1, Int32 number2);
static void Main(string[] args)
{
var addedNumbers = add_numbers(10, 5);
Console.WriteLine(addedNumbers);
Console.ReadLine();
}
}
}
along with the following project settings.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RootNamespace>my_core_console</RootNamespace>
<PlatformTarget>x64</PlatformTarget>
<Platforms>x64</Platforms>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
<ItemGroup>
<None Remove="my_lib.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="my_lib.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
I attempted to target the x64 platform like I did for the full framework console app. However, I am still getting the following error.
Unhandled exception. System.BadImageFormatException: An attempt was made to load a program with an incorrect format. (0x8007000B)
I am not sure what I am missing. Would appreciate any pointer.
The problem is that you set the crate type to dylib
not cdylib
.
According to The Rust Language Reference dylib
is for rust-rust dynamic linking. cdylib
crates a dynamic library with the c abi for use in other programming languages.
Set crate-type
to cdylib
I had exactly the same problem.
Turns out that for new Console project in C# (at least for .NET Framework 4.7.2) the default option is to 'prefer 32 bit code', which will fail to run-time link your x64 rust dll.
In C# project open Project Settings, Build tab and make sure the option 'prefer 32 bit code' is unselected:
User contributions licensed under CC BY-SA 3.0