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

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

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

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

1170閲覧

.NETで配列コピーがしたい

yukijiro1990

総合スコア37

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2018/12/27 07:59

user32dll の関数によくあるようなインタフェースを実現したく思います。

たとえば user32dllに
SendInput(num, inp(0), Marshal.SizeOf(inp(0)))

って関数がありますが、これは inp(0)だけではなく、inp(0)以降の配列要素を処理するのであります。

同じような、つまり配列の始まりの要素を引数としたいのですが。

C++で (int &a)を引数とし、それをDLLにして、.NETからインポートして
実現はしましたが、

それをループで何回も呼び出ししているうちにスタック破壊を起こしてしまいました。

メモリの解放が必要だとは思うのですが、どのタイミングで実施すればよいのでしょうか。

ちなみに出来たけれども、ループしているうちにスタックを破壊したコードは以下になります。

【C++コード】

int __stdcall CPMEM(int &a, int &b, int &k)
{

int i = 0; for (i = 0; i <= k; i++){ *((&a) + i) = *((&b) + i); }

// return *((&a)+1);
return k;
}

【 .NET】

Declare Function CPMEM Lib "ConsoleApplication2.dll" (ByRef a As Integer, ByRef b As Integer, ByRef k As Integer) As Integer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

Dim a(5) As Integer

While True
Writehogehoge(a(0), 5) 'あるデータ内容を, 配列a へ0番目から要素5個分にわたってコピーするうな関数
End While

End Sub

Public Sub Writehogehoge(ByRef aaa As Integer, ByVal k As Integer) '配列指定はByrefにすること
Dim b() As Integer = {100, 200, 300, 400, 500}

CPMEM(aaa, b(0), k) 'ADD(a,b,c) bからaへ番地k個ぶんだけコピーする

End Sub

ちなみに、C++/CLIで同じように、CPMEM(int &a, int &b, int &k)
を作ったところ、.NETでは呼び出せないようでした。

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

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

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

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

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

ozwk

2018/12/27 08:01 編集

なぜわざわざC++でコピーを?
yukijiro1990

2018/12/27 08:05

ユーザには UserFnc( array(0) ) の形で使わせたいのです。
ozwk

2018/12/27 08:11

配列の0番目じゃなくて 配列自体を引数にするのでなにか問題でも?
yukijiro1990

2018/12/27 08:23

いや、User32.dll とかの関数で、そういうインタフェースの関数が多いから、どうやって実装してるのかな、と。 C++を使えばポインタで簡単にできるのですが。。
guest

回答2

0

Array.Copy でできませんか

投稿2018/12/27 08:00

編集2018/12/27 08:02
y_waiwai

総合スコア87749

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

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

yukijiro1990

2018/12/27 08:02

盲点でした・・。 実は Array.Copy 、私自分の作った通信ライブラリで使ってました・・・ ありがとうございました。
yukijiro1990

2018/12/27 08:04

あ、違います。ユーザに使わせる関数で、 array(0)の形のインタフェースを作りたいんです。
y_waiwai

2018/12/27 08:07

そのインターフェースでArray.Copyするとかすれば
guest

0

ベストアンサー

なんでこんなことしなけりゃいけないのかよくわかりませんが

int __stdcall CPMEM(int &a, int &b, int &k)

int __stdcall CPMEM(int &a, int &b, int k)

投稿2018/12/27 08:16

Zuishin

総合スコア28660

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

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

yukijiro1990

2018/12/27 08:24

個数k &にする必要はありませんね。間違いでした。
Zuishin

2018/12/27 08:26

後多分 k に入れる値が間違っています。呼び出し側の処理を正確に書いてください。バイト数でなく要素数を入れてるんじゃないですか?
Zuishin

2018/12/27 08:29

それと呼び出し規約を指定する属性がありません。
Zuishin

2018/12/27 08:29

それから見にくいのでコードはコードブロックで囲んでください。
yukijiro1990

2018/12/27 08:30

そうです。要素数 k のはずなんですけど、なぜか上のコードでも普通に動くから怖いです。 やりたいことは User32.DLLとかの関数とかでよくある SendInput( array[1]) ←なインタフェースです。つまり array[1]をユーザが渡せば、 array[1]以降の要素を関数内で処理する・・ ということをしたいのです、。
yukijiro1990

2018/12/27 08:30

呼び出し規約ってなんですか?
Zuishin

2018/12/27 08:31

そうなると unsafe になると思いますが、vb では使えなかったと思います。
yukijiro1990

2018/12/27 08:32

ちなみに、今私が質問してることって、.NET だけじゃ無理ですよね? だってarray[1]の次のアドレスを見るわけだから。
yukijiro1990

2018/12/27 08:33

はい。unsafe です。 アンマネージコードを、CLIでラッパしたら、マネージコードになりますか? C++/CLI で同じように int &a な引数の関数を作ったのですが、.NET側から 呼び出せませんでした。
Zuishin

2018/12/27 08:46 編集

ラップした関数が配列の特定要素のポインタ対応していないのでできません。
Zuishin

2018/12/27 08:43

よく見たら k は ByRef がついているので最初ので正しいですね。
yukijiro1990

2018/12/27 08:50

アンマネージコードのラップについて勉強したいのですがお薦めの書籍てありませんか?
Zuishin

2018/12/27 08:51

不可能を可能にする書籍は知りませんね。 .NET の配列と C の配列は違います。また VB ではポインタを使えません。 ですから、呼び出し側に要素のアドレスを強いる限り不可能です。
yukijiro1990

2018/12/27 09:30

USER32.DLL の関数は、おそらくループさせてもスタックを破壊しないとは思いますが、 メモリの解放をやっているということでしょうか。 ソースコードってないんでしょうか。
yukijiro1990

2022/03/25 12:48

>不可能を可能にする書籍は知りませんね。.NET の配列と C の配列は違います。また VB ではポインタを使えません。 不可能なのは承知で聞いてみました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問