1

I do not really believe that this question was never asked before, but i really tried to search without success, if you got a link to an already answered similar question, please share it.

I am porting a C++/Win32 program to C++/CLI, and, of course, I am trying to make the fewer number of modifications possible to the code in order to speed-up the re-testing phase.

I am having some trouble due to global functions having objects as parameters, here a short example:

Class header file

namespace MyNamespace {
    public ref class MyClass {
    public:
        void test();
    };
}

Class cpp file

using MyNamespace;

void myFunction(MyClass ^obj);

void MyClass::test() {
    myFunction(this);
}

And here comes the problem: if I leave out myFunction from MyNamspace, it cannot use MyClass as a parameter's type. If I include myFunction in MyNamespace, every cpp file will compile correctly, but i will get a linker error "LNK2028 unresolved token".

An idea is to define a new class and include myFunction as a public static method, but to do this will be a long job, because myFunction, in the real project, is not alone... Any other idea?

Nikita
  • 6,270
  • 2
  • 24
  • 37
Beddu
  • 21
  • 4
  • You do define (implement) `myFunction` somewhere? If that's the "token" (symbol I think the error message actually is) that is unresolved (please include the *complete* error message, without editing). – Some programmer dude Oct 18 '16 at 09:18
  • 1
    the "command line interface" tag is silly the CLI in "C++/CLI" stands for "Common Language Infrastructure" – PeterT Oct 18 '16 at 09:42
  • 2
    Well, you just wrote that prototype declaration to suppress a compiler error message that told you that you were doing it wrong. Didn't stop you from doing it wrong however, now the linker discovers that you don't actually have that function. Pretty essential about C++/CLI is that you do **not** directly translate native C++ to managed code but only write wrapper classes for the *public* interface to your library. Leave all the internal plumbing as-is. And customize those wrappers so they are easy to use with the managed type system. http://stackoverflow.com/a/2691448/17034. – Hans Passant Oct 18 '16 at 09:42

2 Answers2

0

If MyClass is in MyNamespace and myFunction is not, you could use MyClass with full name qualification:

void myFunction(MyNamespace::MyClass ^obj);

Of course your myFunction should be implemented somewhere.

Nikita
  • 6,270
  • 2
  • 24
  • 37
  • Of course it is implemented, I made the wrong assumption that it was obvious. Thanks I will try that and let you know. – Beddu Oct 18 '16 at 10:54
  • So, I have to say it is easier than I expected! It is enough to keep the global functions ( myFunction ) out of the namespace ( MyNamespace ) and include the prototypes in the cpp file where the class methods ( MyClass::test ) are implemented. Then in the cpp file where the global functions are implemented I must tell the compiler that I will use classes from a namespace ( using namespace MyNamespace; ) so i dont need to specify it in every declaration. I will write an answer with the correct code. – Beddu Oct 18 '16 at 15:42
0

I made some tests following Nikita's suggestion, and the final, working, code looks like this:

Class header file

namespace MyNamespace {
    public ref class MyClass {
    public:
        void test();
    };
}

Class cpp file

void myFunction(MyClass ^obj);

using MyNamespace;

void MyClass::test() {
    myFunction(this);
}

Global function cpp file

using namespace MyNamespace;

void myFunction(MyClass ^obj) {
    //do something
}

Using this approach in global function's cpp file is possible to use MyClass while myFunction remains (or pretend to remain) global, and MyClass::test can access myFunction even if not in the same namespace, just using a prototype declaration as in "old" c++.

Beddu
  • 21
  • 4