System.BadImageFormatException while calling a rust dll from netcore c# console app

2

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.

c#
.net-core
rust
interop
asked on Stack Overflow Aug 27, 2020 by Sayan Pal

2 Answers

0

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

answered on Stack Overflow Aug 27, 2020 by Nick Farley
0

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:

Prefer 32 bit code should be unselected

answered on Stack Overflow Feb 12, 2021 by PiotrK

User contributions licensed under CC BY-SA 3.0