0

多数の.hおよび.libファイルをネイティブC++からマネージC++に移植して、最終的にC#で参照される.dllとして使用できるように取り組んでいます。

どうか、すべてを.NETに移植する方がはるかに簡単だと思いますが、できればそうすることもできます。これはサードパーティであり、使用できるのは.lib(エクスポートなし)ファイルと.hファイルだけです。

仮想関数に到達するまですべてが順調に進んでおり、現在、デリゲートの問題が発生しています。

私が得ているエラーの中には次のものがあります:

エラーC3756:'ThreadFunc':デリゲート定義が既存のシンボルと競合し
ますエラーC2079:'MyWrapTest :: MyThreadWrap::m_threadAttr'は未定義のクラスを使用します'MyWrapTest:: MyThreadAttrWrap'エラーC2664:' MyWrapTest :: AutoPtr :: AutoPtr(T *) ':パラメータ1を' MyWrapTest::MyThreadAttrWrap'から'MyThread*'に変換できません

わかりやすくするために、ネイティブコードと現在取り組んでいるものを含めます。まず、ネイティブコード:

#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;
};
}
4

2 に答える 2

0

ユージーン、

入力ありがとうございます。長い一日の後に疲れた目を愛さなければなりません。AutoPtrが間違ったタイプを宣言しているのは正解でした。

ネイティブスレッドオブジェクトの「シャドウコピー」については、.NETでネイティブオブジェクトの管理が正しく行われていることを確認するために、Microsoftが推奨する十分に文書化された方法に従っています。

MSDNの記事

代議員の問題は、疲れた目にも関連していました。既存の(ネイティブ)関数が新しいデリゲートと同じスペースに存在できるように、デリゲート名を変更する必要がありました。

前方宣言に関してはまだ問題がありますが、すぐに解決できると確信しています。

于 2009-07-15T14:34:30.957 に答える
0

コンストラクターでm_NativeMyThreadを再度定義するのはなぜですか?これによりローカル変数になります。おそらくこれが必要です。

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

または

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

私は通常.Netを使用しないため、AutoPtrのセマンティクスについてはよくわかりませんが、ローカルシャドウを作成するのではなく、メンバーオブジェクトを変更する必要があります。

エラーについては、ここでAutoPtrタイプの新しいローカルオブジェクトを作成し、MyThreadAttrWrapタイプの引数を1つ渡します。MyThreadWrap(MyThreadAttrWrap tta){AutoPtr m_NativeMyThread(tta); }; (私はそれをC ++として読んでいます、.Netが物事を混乱させるなら私を訂正してください)

必要なのは、コンストラクターに渡されたMyThreadAttrWrapから抽出されたアンマネージMyThreadAttr*オブジェクトで構築された新しいMyThreadオブジェクトでm_NativeMyThreadを初期化することです。

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

ところで、所有権には十分注意してください。あなたが投稿したコードから、MyThreadがMyThreadAttrを所有しているか、それとも外部で所有されているかは不明です。また、AutoPtrは、囲まれたポインターを所有しています(適切な名前が付けられている場合)。

于 2009-07-15T00:21:07.203 に答える