質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

7656閲覧

C++のポインターを使用したコードをC#に移植したい

fumiasi

総合スコア12

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2017/04/04 09:22

編集2017/04/04 09:33

###前提・実現したいこと
C++で作成されたソースをC#に移植したいと考えているのですが、
ポインターを複数使用されているコードの部分で苦戦しています。
引数等であればref、関数であればunsafeで対応出来るかと思うのですが、
メンバー変数等で保持している部分等はどうすればよいでしょうか。

###移植しようとしているデータ例

C++

1typedef int (*FUNK_DATA)(cData *data); 2 3public class cData 4{ 5public: 6 FUNK_DATA pFunk; // 関数ポインター 7 cData* pBefore; // 前のデータ 8 cData* pNext; // 次のデータ 9 10 int data; 11} 12 13public class cSystemData 14{ 15private: 16 cData* pRealiz; // 先頭のデータアドレス 17 cData** ppStart; // 先頭アドレス 18 int* num; // データ数 19 int max; 20 cData* pEmpty; // 未使用データ 21 22public: 23 bool Init(int num) 24 { 25 max = num; 26 pRealiz = (cData*)MALLOC( sizeof(cData) * max ); 27 ppStart = (cData**)MALLOC( sizeof(cData*) * max ); 28 num = (int*)MALLOC( sizeof(int) * max ); 29 } 30 31 void Create(cData *data) 32 { 33 // 初期化 34 for(i = 0 ; i < max ; i++) 35 { 36 ppStart[ i ] = NULL; 37 num[ i ] = 0; 38 } 39 40 pEmpty = &data[0]; 41 42 for(i = 0 ; i< max ; i++) 43 { 44 if(i == 0) 45 { 46 data[ i ].pBefore = NULL; 47 data[ i ].pNext = &data[ i + 1 ]; 48 } 49 else if( i== max-1) 50 { 51 data[ i ].pBefore = &data[ i - 1 ]; 52 data[ i ].pNext = NULL; 53 } 54 else 55 { 56 data[ i ].pBefore = &data[ i - 1 ]; 57 data[ i ].pNext = &data[ i + 1 ]; 58 } 59 data[ i ].data = 0; 60 } 61 } 62 63 cData* GetStartData(int idx) 64 { 65 return ppStart[idx]; 66 } 67 68 void Change(FUNK_DATA pFunk, cData *data) 69 { 70 data->pFunk = pFunk; 71 } 72} 73

上記のソースをC#に書き換える場合、どのように書き換えれば良いでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

こんにちは。

C#の参照≒C++のポインタです。そのように読み替えてプログラムすることが理論的には出来るはずです。
MALLOCと多重ポインタの部分はそれなりに変更が必要です。
MALLOCはnew 型名[max];に置き換えることができそうなコードになってます。
多重ポインタppStartも単にポインタの配列なので同様です。

しかし、C#の参照が事実上ポインタであることを積極的に使うコードは避けた方が良いと思います。C#は見た目上、値型と参照型の構文が同じなのでかなりハマります。経験上、地獄を見る可能性が高いです。

また、元のC++プログラムがC++プログラムとして成立していません。多数のコンパイル・エラーがでます。少しだけ修正してみましたが、とても手に追えるレベルではないです。
既にデバッグ完了したC++プログラムが存在するわけでないのでしたら、新規にC#として開発した方がうまくいくように感じます。

投稿2017/04/04 09:56

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fumiasi

2017/04/04 10:05

ご返答、ありがとうございます。 デバッグが完了したプログラムは存在するのですが、諸事情により抜粋したデータになります。 質問の例用に抜粋と変数名を変更し、ビルドテストまでしてなかったです。 申し訳ありません。 どうしても、元データに合わせて移植する必要があったので、良い対応方が無いものかと質問させて頂きました。 ひとまず、配列等に置き換えて対応していきます。
Chironian

2017/04/04 10:26

なるほど。それはたいへんそうですね。 C#のclass型の変数は全て参照型(=C++のポインタ)になります。 例えば、pRealiz は下記で領域確保することになります。 cData[] pRealiz = new cData[max]; for (int i=0; i < max; ++i) pRealiz[i]=new cData; しかし、使う時は普通に使います。 pRelaiz[i].data=100;等 そして、ppStartは、pRealizと異なり、ポインタ配列なので実体確保を省略しただけのものになります。 cData[] ppStart = new cData[max]; そこに、積極的にポインタとしての使い方を導入すると、恐らくパニックになります。気がついたら参照先が意図しないインスタンスにすり替わってます。C++であれば中身を代入する構文で、ポインタがコピーされますから。(しかし、C#でも値型の変数なら代入構文で中身がコピーされます。) ポインタなのか配列なのかポインタの配列なのか区別をつけるための工夫をすることをお勧めします。バッと思いつくのは変数名の命名規則くらいですが、それだけでは弱いかも知れません。
fumiasi

2017/04/04 12:30

追記ありがとうございます。 参考にされて頂きます。 区別につきましては、ひとまず命名規則で対応していきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問