I am working on porting a large number of .h and .lib files from native C++ to Managed C++ for eventual use as a referenced .dll in C#.
Please, I know it’d be a lot easier to port the whole thing to .NET, but if I could I would. It’s 3rd party and all I have are .lib(no exports) and .h files to work with.
Everything has been going smoothly until I hit virtual functions and now I’m having some delegate issues.
Among the errors I’m getting are:
error C3756: ‘ThreadFunc’: delegate definition conflicts with an existing symbol
error C2079: ‘MyWrapTest::MyThreadWrap::m_threadAttr’ uses undefined class ‘MyWrapTest::MyThreadAttrWrap’
error C2664: ‘MyWrapTest::AutoPtr::AutoPtr(T *)’ : cannot convert parameter 1 from ‘MyWrapTest::MyThreadAttrWrap’ to ‘MyThread *’
For clarity, I’ll include the native code and the stuff I’m working on now. First, native code:
#ifndef MYTHREAD_HPP
#define MYTHREAD_HPP
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#define STDCALL unsigned __stdcall
typedef unsigned (__stdcall *ThreadFunc)(void*);
#else
#define STDCALL void*
typedef void* (*ThreadFunc)(void*);
typedef unsigned int HANDLE ;
#endif
#include "generaltypes.hpp"
class MyThreadAttr;
class MyThread
{
public:
MyThread(void);
MyThread(MyThreadAttr * tta);
virtual ~MyThread() {};
virtual HANDLE start(ThreadFunc,void *, unsigned *);
virtual int stop();
static void wait(HANDLE);
#ifdef WIN32
static void wait(HANDLE, int);// msec timeout required since 'cancelThread' is no-op
#endif
static void sleep(unsigned int);
static int32 cancelThread(HANDLE hThread); // no-op on Windows (returns -1)!
#ifndef WIN32
static void setCancelStates(void);
static void endProcess();
#endif
protected:
MyThreadAttr * m_threadAttr;
void setThreadAttr(MyThreadAttr * tta);
};
#endif
AND THE NEW STUFF I’M DEVELOPING:
#pragma once
#ifdef WIN32
#include <winsock2.h>
#include <windows.h>
#define STDCALL unsigned __stdcall
//typedef unsigned (__stdcall ThreadFunc)(Object^);
#else
#define STDCALL Object^
typedef unsigned int HANDLE;
#endif
#include "gentypes.hpp"
#include "AutoPtr.h"
#include "MyThread.hpp"
using namespace System;
using namespace System::Runtime::InteropServices;
namespace MyWrapTest
{
public delegate Object^ ThreadFunc(Object^ o);
ref class MyThreadAttrWrap;
//#include "MyThreadAttrWrap.h"
public ref class MyThreadWrap
{
public:
MyThreadWrap(void)
{
AutoPtr<MyThread> m_NativeMyThread(new MyThread);
};
MyThreadWrap(MyThreadAttrWrap tta)
{
AutoPtr<MyThread> m_NativeMyThread(tta);
};
/*virtual ~MyThreadWrap(){};
virtual HANDLE start(ThreadFunc,System::Object^, unsigned ^);
virtual int stop();*/
static void wait(HANDLE h)
{
m_NativeMyThread->wait(h);
};
#ifdef WIN32
static void wait(HANDLE h, int i) // msec timeout required since 'cancelThread' is no-op
{
m_NativeMyThread->wait(h, i);
};
#endif
static void sleep(unsigned int i)
{
m_NativeMyThread->sleep(i);
};
static int32 cancelThread(HANDLE hThread); // no-op on Windows (returns -1)!
#ifndef WIN32
static void setCancelStates(void);
static void endProcess();
#endif
protected:
MyThreadAttrWrap m_threadAttr;
void setThreadAttr(MyThreadAttrWrap tta);
private:
AutoPtr<MyThread> m_NativeMyThread;
};
}
Why do you define m_NativeMyThread in constructors again — this makes it local variable, you probably want this:
Or
I don’t usually use .Net, so I’m not sure about semantics of AutoPtr, but you want to change your member object, not create a local shadow.
As for the error, here you create new local object of type AutoPtr and pass it one argument of type MyThreadAttrWrap.
MyThreadWrap(MyThreadAttrWrap tta)
{
AutoPtr m_NativeMyThread(tta);
};
(I’m reading it as C++, correct me if .Net confuses things)
What you want is to initialize m_NativeMyThread with new MyThread object that was constructed with unmanaged MyThreadAttr* object that was extracted from MyThreadAttrWrap that was passed in to your constructor.
BTW, be very carefull with ownership. From code you posted it is unclear if MyThread owns MyThreadAttr or if it is owned externally. And AutoPtr owns its enclosed pointer (if it at all named properly).