1

I've looked over a few questions with a title just like this one, but they either do not talk about command line, or don't seem to work for me for some reason. From what I have read, it seemed as if I could "simply" do the following:

The dummy code (C#):

using System;

public static class Foo {
    public static void Bar() {
        Console.WriteLine("o3o");
    }
}

More dummy code (Visual C++):

#using <test.dll>

int main() {
    Foo::Bar();
    return 0;
}

C# DLL compiled using:

csc /out:test.dll /t:library src\cs\Foo.cs

Visual C++ object file compiled using:

cl /Ox /clr /AI. /c src\vc\test.cpp

Executable compiled using:

link /out:test.exe test.obj

The following exception is thrown upon running the executable:

Unhandled Exception: System.TypeLoadException: Could not load type 'Foo' from assembly 'test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'.
   at main()
   at mainCRTStartup()

I have a strong feeling that I was supposed to also reference the DLL in the link phase, but I couldn't find any option for linking a DLL similar to GCC's -l option. Attempting to pass the DLL along with the .obj to link causes it to tell me that linking assemblies is not supported. Interestingly, though, if I build a .netmodule instead of a DLL, i.e. by:

csc /out:test.dll /t:module src\cs\Foo.cs

and changing the #using directive to

#using <test.netmodule>

the executable runs without error. This feels a bit weird, for I don't think anybody packages code in .netmodules (what are .netmodules, anyway?).

3
  • Think of a .netmodule as the equivalent of a .lib in plain C++, that's why you can link with it. Managed code is somewhat different, you don't just link .dll files together. Why are you trying to link them in the first place? Your C++/CLI exe can just reference the C# dll without linking with it, just put the dll in the same directory as the exe. Commented Feb 6, 2017 at 16:20
  • The DLL does reside in the same directory as the executable, but the aforementioned exception is thrown upon running it. Commented Feb 6, 2017 at 16:24
  • Ok I looked at the issue and posted an answer. I just wanted to make sure you didn't get caught by the #1 trap when mixing C# and C++/CLI first :) (the default configuration of the IDE is kind of broken - it makes it hard to do this for no reason by not putting the output files in the same place - as you have used directories in your commands I figured you could have had the same issue, but then I realized what /AI. was) Commented Feb 6, 2017 at 16:50

1 Answer 1

3

All of your steps should have worked, but one very simple issue is preventing your program from running.

Namely: Your C# DLL assembly name is test, and your C++/CLI exe assembly has the same name. They both have the same identity.

So when looking for Foo::Bar in the test assembly, the loader first checks if the assembly is loaded in the AppDomain. It is - it's your C++/CLI exe, and you can't have several assemblies with the same identity loaded simultaneously within the same AppDomain. Your C# dll wasn't even given a try.

Just change either one of them and everything will work fine:

link /out:test2.exe test.obj

As for what's a .netmodule, it's the format used for linking managed code statically, that's why you managed to link your C# code with your C++/CLI code without issues. It's roughly the equivalent of a .lib file for managed code.
And you're right, it's not used very often.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.