Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++/cli interface header file

I have a C++ project (visual studio 2010) which consists of native code and c++/cli code as well. I cant compile the whole project with /clr, so I just do it for the respective c++/cli files. My Problem is that a header file cant be compiled with /clr, but I want to make some c++/cli functions reusable within the whole project and therefor define the method prototypes in a header file to include it in every file where I need it. Is there a solution? I have tried to define some mixed code method prototypes in a header file, but /clr must be switched on for that to compile.

Here is my example:

Test.h

#include <Windows.h>
#include <vector>
#include <string>

using std::vector;
using std::string;

#include <msclr/marshal.h>

#pragma managed

using namespace msclr::interop;
using namespace System;
using namespace System::IO;
using namespace System::Runtime::InteropServices;

public ref class Test
{
public:
    int Foo();
};

Test.cpp

#include "Test.h"

int Test::Foo()
{
    return 4;
}

Intellisense is complaining with errors in Test.h like c++/cli must be enabled to use #using. But I think this is negligible and it would compile anyway.

Compilation aborts with a Linker Error (sry, i have german VS version)

Fehler  6   error LNK1255: Fehler bei Verknüpfung aufgrund von Metadatenfehlern.    
Fehler  4   error LNK2022: Fehler bei Metadatenoperation (8013118D) : Duplizierte Typen (_PROPSHEETPAGEA) wurden gefunden, aber die Typenlayoutinformationen sind nicht konsistent: (0x02000198).   
Fehler  5   error LNK2022: Fehler bei Metadatenoperation (8013118D) : Duplizierte Typen (_PROPSHEETPAGEW) wurden gefunden, aber die Typenlayoutinformationen sind nicht konsistent: (0x020001d1).   

I definitely dont have a duplicate class "Test" elsewhere, so I dont know where the duplicate comes from. What are typelayout informations and why are they not consistent?

like image 729
Michbeckable Avatar asked Dec 13 '11 15:12

Michbeckable


1 Answers

I think you've all missed the point.

You can easily compile a native project with some /clr classes. (For example: A native DLL will still function like a native DLL, however, it can also be loaded into C#, and it's /clr compiled classes can then be accessed in C#.)

That's why such an option exist at the file level. (Right click .cpp: Properties->C\C++->Common Language Runtime Support- /clr)

The problem is:

Communicating between native\managed classes, since .H files cannot be set to use /clr, those cannot be used to reference a managed class elsewhere including other /clr files within the same project. (ie, you can create /clr files, but, they can't talk to each other, nor can you reference them within native portions of the project.)

The best solution I can find is to create a "glue" C# .dll file.

Create a new C# class library, add the Native DLL as a reference, then compile.

Now, in your native project, you can load the C# DLL, and access the natives /clr stuff through it. (The managed code you reference this way can be used with native\managed code.)

It's very possible, but, I cannot find a straightforward way to accomplish this.

That's what the topic is about, there seems to be no way to reference /clr classes due to header files not working when you set /clr at the file level. (ie, a header cannot contain /clr code unless the WHOLE project is set to /clr.)

There must be a way to reference /clr stuff without headers, or C++\CLI is just broken, I can easily load native code into /clr files by using pragma + headers, however, the reverse is looking impossible short of my "glue" solution.

That is what I believe this topic is about.


My method works, but, it's very tricky to get right, and compilation is a pain due to circular dependencies, etc,.

I really hope there is a proper way to do this, I've been looking, and my search led me here...

The real solution, would be to make .h files support /clr, then you could define your managed class in the header, and be able to freely reference it using standard methods, like include\using\pragma, etc,.

like image 113
Smoke Avatar answered Sep 19 '22 23:09

Smoke