- ベストアンサー
VB.NETからC++のdll連携(double)
- プログラム初心者です。double型の配列をVB2010とC++で作成したdllで連携したいのですが、値が正しく渡されません。
- 値が正しく渡せるにはどうしたら良いでしょうか?C++ではSafeArrayの扱いになるとのことですが、方法が良く分かりません。
- VBソースコードで作成したdouble型の配列をC++のdllで正しく受け取りたいです。方法を教えてください。
- みんなの回答 (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; といった具合ですよ
その他の回答 (3)
- redfox63
- ベストアンサー率71% (1325/1856)
このソースですと 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 );
補足
上記の様に変更しましたが、正しい値が返って来ませんでした。
- tsukasa-12r
- ベストアンサー率65% (358/549)
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の参照ができません。
- redfox63
- ベストアンサー率71% (1325/1856)
単純な置き換えでうまくいきませんか? 当方の環境では 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の内容が期待したとおりではないのか 何がまずいのかを明記しましょう
補足
捕捉致します。 1.1などの小数点を含む値が計算できないということです。 上記の様に変更致しましたが、同様の結果でした。
お礼
有難うございました。 無事動作いたしました。