プログラム初心者です。
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も見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「指定されたキャストは有効で...
-
#define _CRT_SECURE_NO_WARNIN...
-
へんな現象
-
【C++】関数ポインタの使い方
-
(int *)の意味
-
C言語での引数の省略方法
-
if と配列の組み合わせ
-
複数桁10進数の*桁目だけを抽出...
-
C言語でDxlibを使って3x3の奇数...
-
(マルチスレッド)_beginthrea...
-
C言語での奇数の和
-
ラップ関数とはどんなものですか?
-
整数データの配列から同じ値の...
-
system関数がうまくいかない
-
足して100になるような乱数のア...
-
教えてください(丸罰ゲーム)
-
ファイルに含まれるアルファベ...
-
囚人のジレンマゲーム C言語
-
C言語の配列をC++のvectorに高...
-
プログラミングペーパーテスト ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
「指定されたキャストは有効で...
-
C言語 配列と関数の練習問題
-
複数桁10進数の*桁目だけを抽出...
-
(int *)の意味
-
if と配列の組み合わせ
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
c言語
-
足して100になるような乱数のア...
-
C言語初心者です、、、お助けく...
-
数字列を3桁ごとにカンマで区切...
-
C言語 エラーの原因がわからな...
-
実数の整数部,小数部の取得
-
課題でつまってます・・・
-
商と剰余を同時に求める(C言語)
-
C言語の配列をC++のvectorに高...
-
std::set<int> で、ある値が何...
おすすめ情報