
プログラム初心者です。
double型の配列をVB2010とC++で作成したdllで連携したいのですが、値が正しく渡されません。
値が正しく渡せるにはどうしたら良いでしょうか?
以下がその内容です。(int型の場合)これをdouble型で渡したいのですが。
C++ではSafeArrayの扱いになるとのことですが、方法が良く分かりません。
VBソース
-----------------
' Arrays.vb
Imports System
Imports Microsoft.VisualBasic
Imports System.Runtime.InteropServices
Friend NotInheritable Class NativeMethods
Private Sub New()
End Sub
Declare Function TestArrayOfInts Lib "makedll.dll" ( _
<[In](), Out()> ByVal myArray() As Integer, ByVal size As Integer) As Integer
End Class
Public NotInheritable Class App
Private Sub New()
End Sub
Public Shared Sub Main()
' *************** array ByVal **************
Dim array1(9) As Integer
Console.WriteLine("Integer array passed ByVal before call:")
Dim i As Integer
For i = 0 To array1.Length - 1
array1(i) = i
Console.Write(" " & array1(i))
Next i
Dim sum1 As Integer = NativeMethods.TestArrayOfInts(array1, array1.Length)
Console.WriteLine(ControlChars.CrLf & "Sum of elements:" & sum1)
Console.WriteLine(ControlChars.CrLf & "Integer array passed ByVal after call:")
For Each i In array1
Console.Write(" " & i)
Next i
Console.Read()
End Sub
End Class
//**********************************
C++作成dllソース(makedll.cpp)
extern "C" MAKEDLL_API int TestArrayOfInts( int* pArray, int size )
{
int result = 0;
for( int i = 0; i < size; i++ )
{
result += pArray[ i ];
pArray[ i ] += 100;
}
return result;
}
//**********************************
C++作成dllソース(makedll.h)
#ifdef MAKEDLL_EXPORTS
#define MAKEDLL_API __declspec(dllexport)
#else
#define MAKEDLL_API __declspec(dllimport)
#endif
extern "C" MAKEDLL_API int TestArrayOfInts( int* pArray, int size );
//**********************************
C++作成dllソース(makedll.def)
LIBRARY makedll.dll
EXPORTS
TestArrayOfInts PRIVATE
No.4ベストアンサー
- 回答日時:
DLL側から 少数を含む合計を返すなら
VB側の宣言を
Declare Function TestArrayOfDoubles Lib "makedll.dll" ( _
<[In](), Out()> ByVal myArray() As Double, ByVal size As Integer) As Double
に変更
DLL側を
extern "C" MAKEDLL_API double __stdcall TestArrayOfDoubles( double* pArray, int size )
{
double result = 0;
といった具合ですよ
No.3
- 回答日時:
このソースですと C++側の呼び出し規約が __cdeclになってしまうので スタックの使い方が違うと思います
関数宣言/実装を __stdcallにして見ましょう
C++作成dllソース(makedll.cpp)
extern "C" MAKEDLL_API int __stdcall TestArrayOfDoubles( double* pArray, int size )
{
int result = 0;
for( int i = 0; i < size; i++ )
// makedll.h
extern "C" MAKEDLL_API int __stdcall TestArrayOfDoubles( double* pArray, int size );
No.2
- 回答日時:
Double 型を配列で渡し、合計を返す関数の例です。
C++ DLL 側
stdafx.h
==============================================
#pragma once
#include "targetver.h"
#define WIN32_LEAN_AND_MEAN // Windows ヘッダーから使用されていない部分を除外します。
#include <windows.h>
#include <oaidl.h>
==============================================
DoubleArrayTest.cpp
==============================================
#include "stdafx.h"
extern "C" __declspec(dllexport) double SumOfDoubleArray( LPSAFEARRAY *ppsa, int size )
{
double *pda;
double sum = 0.0;
SafeArrayAccessData( *ppsa, (void**)&pda );
for( int i = 0; i < size; i++ ) {
sum += *pda;
pda++;
}
SafeArrayUnaccessData( *ppsa );
return sum;
}
==============================================
VB 側
==============================================
Imports System.Runtime.InteropServices
Public Class Form1
Private Declare Function SumOfDoubleArray Lib "DoubleArrayTest.dll" _
(<MarshalAs(UnmanagedType.SafeArray)> ByRef array() As Double, ByVal count As Integer) As Double
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim da() As Double = {1.2, 3.4, 5.6}
Dim sum As Double = SumOfDoubleArray(da, da.Length)
Debug.WriteLine(sum)
End Sub
End Class
==============================================
この回答への補足
回答ありがとうございます。
上記のソースで動作確認したところ、
PInvokStackImbalance が検出されました。
PInvokeシグネチャがアンネージターゲット シグネチャ一致していないことが原因と出ます。
また、stdafx.h内の記述のtargetver.hの参照ができません。
No.1
- 回答日時:
単純な置き換えでうまくいきませんか?
当方の環境では IntegerをDoubleに置き換えただけで 期待通りの動作になっていますよ
'arrays.vb
Declare Function TestArrayOfDoubles Lib "makedll.dll" ( _
<[In](), Out()> ByVal myArray() As Double, ByVal size As Integer) As Integer
Dim array1(9) As Double
Dim sum1 As Integer = NativeMethods.TestArrayOfDoubles(array1, array1.Length)
// makedll.cpp
extern "C" MAKEDLL_API int TestArrayOfDoubles( double* pArray, int size )
{
int result = 0;
for( int i = 0; i < size; i++ )
{
result += (int)pArray[ i ];
pArray[ i ] += 100;
}
return result;
}
// makedll.h
extern "C" MAKEDLL_API int TestArrayOfDoubles( int* pArray, int size );
// mamkedll.def
TestArrayOfDoubles PRIVATE
といった変更です
2次元(以上の)配列や 多段配列の場合は SafeArray経由にしないと操作がうまくないのですが
単純な1次元配列なら doubleやSingle(float)やInteger(int)ならポインタで受けてやればいいと思います
sum1の計算がうまく出来ないのか
DLLへ飛んでいってかえってきたときの arrayの内容が期待したとおりではないのか
何がまずいのかを明記しましょう
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) ①ExcelVBAでカレンダーを作り、別のユザーフォームで日付を入力したいのですがエラーになります。 1 2023/02/17 18:39
- Visual Basic(VBA) vbaの計算 if elseと範囲について 6 2022/11/26 01:49
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたいの続き 5 2023/01/24 00:16
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- Visual Basic(VBA) VBAプログラミング 2 2022/11/27 12:07
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) 九九の答えの計算 3 2022/12/20 22:13
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) 別シートから年齢別の件数をカウントしたい 6 2023/01/23 12:00
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
複数桁10進数の*桁目だけを抽出...
-
「指定されたキャストは有効で...
-
【C++】関数ポインタの使い方
-
C言語での引数の省略方法
-
構造体の勉強中です 合計点の高...
-
#define _CRT_SECURE_NO_WARNIN...
-
(int *)の意味
-
実数の整数部,小数部の取得
-
入力された数字を大きい順に並...
-
Listの<Label>と<PictureBox>
-
int型の変数値をバイト列として...
-
fprintfでの文字化け
-
C言語でDxlibを使って3x3の奇数...
-
比較回数と交換回数表示について
-
C言語について教えてください。
-
ファイルから読みこむ方法
-
C言語初心者です、、、お助けく...
-
配列変数のポインターが勝手に...
-
ポインタによる関数への配列渡し
-
C言語、行列の積を求めるプログ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
C言語 エラーの原因がわからな...
-
#define _CRT_SECURE_NO_WARNIN...
-
ラップ関数とはどんなものですか?
-
【C++】関数ポインタの使い方
-
実数の整数部,小数部の取得
-
int型の変数値をバイト列として...
-
std::set<int> で、ある値が何...
-
PowerShellがうまくいかない
-
(int *)の意味
-
CStringの配列要素を関数で受け...
-
ColorをRGBで指定する方法
-
「{ } で囲むだけ」は正しい?
-
acceptをalarmでタイムアウトさ...
-
if と配列の組み合わせ
-
read関数をノンブロッキングで...
-
(マルチスレッド)_beginthrea...
-
int16_t の _t は何?
おすすめ情報