2009-07-14 61 views
0

我正在從本地C++移植大量的.h和.lib文件到託管C++作爲C#中引用的.dll最終使用。本機C++託管C++到C#

請問,我知道將整個東西移植到.NET會容易得多,但如果我能的話。這是第三方,我所有的.lib(無導出)和.h文件可以使用。

一切都一直順利,直到我打虛擬功能,現在我有一些代表問題。

在我得到的錯誤是:

錯誤C3756: '的ThreadFunc':委託定義衝突與現有的符號
錯誤C2079: 'MyWrapTest :: MyThreadWrap :: m_threadAttr' 使用未定義類'MyWrapTest :: MyThreadAttrWrap' 錯誤C2664: 'MyWrapTest :: AutoPtr :: AutoPtr(T *)':不能從 'MyWrapTest :: MyThreadAttrWrap' 轉換參數1至 'MyThread的*'

爲了清楚起見,我將包括本機代碼和我正在處理的內容W上。首先,本地代碼:

#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 

和新的東西,我正在開發:

#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; 
}; 
} 
+0

突出顯示所有代碼並點擊菜單頂部的0101按鈕。 – jkeys 2009-07-14 22:57:03

回答

0

你爲什麼再次構造定義m_NativeMyThread - 這使得局部變量,你可能想這一點:

MyThreadWrap() 
    : m_NativeMyThread(new MyThread) 
{ 
}; 

或者

MyThreadWrap() 
{ 
    m_NativeMyThread = AutoPtr<MyThread>(new MyThread); 
}; 

我通常不使用.Net,所以我不確定AutoPtr的語義,但是你想改變你的成員對象,而不是創建一個本地陰影。

至於錯誤,在這裏您創建一個新的AutoPtr類型的本地對象並將其傳遞給MyThreadAttrWrap類型的一個參數。 MyThreadWrap(MyThreadAttrWrap tta) { AutoPtr m_NativeMyThread(tta); }; (我讀它作爲C++,糾正我,如果淨混淆的東西)

你想要的是與不同之處是從在通過MyThreadAttrWrap提取非託管MyThreadAttr *對象構造的新MyThread的對象初始化m_NativeMyThread到你的構造函數。

MyThreadWrap(MyThreadAttrWrap tta) 
{ 
    m_NativeMyThread = AutoPtr<MyThread>(new MyThread(tta.GetNativeAttr())); 
}; 

順便說一句,要非常小心所有權。從您發佈的代碼中,不清楚MyThread是否擁有MyThreadAttr,或者它是否屬於外部。 AutoPtr擁有它的封閉指針(如果它的名字正確)。

0

尤金,

感謝您的意見。經過漫長的一天之後,愛上了疲憊的眼睛。 AutoPtr聲明瞭錯誤的類型,這是正確的。

至於本地線程對象的「影子副本」,我確實遵循了Microsoft建議的一個記錄良好的練習,以確保本機對象管理在.NET中正確完成。

MSDN Article

的委託問題涉及疲憊的眼睛爲好。我需要更改委託名稱以允許現有(本地)功能與新委託存在於相同的空間中。

我仍然有一些問題與前瞻性聲明,但我敢肯定我可以很快清除。