以下のAAA.cというソースプログラムのaaa()関数内で決めた値を
BBB.cというプログラムの*yに引数か戻り値で入れ、後でひとつずつ
際、取り出す方法が分かりませんし、引数と戻り値のどちらを使えばいいかも
分かりません。
初歩的な質問かもしれませんが、どのような考え方で取り組めばいいのでしょうか?
よろしくお願いします。
AAA.c
///////////////////////////////////////////////////////////
double aaa(double u1,double u2,double u3,double u4)
{
u1=1;
u2=2;
u3=3;
u4=4;
return();
}
///////////////////////////////////////////////////////////
BBB.c
///////////////////////////////////////////////////////////
extern double aaa(double u1,double u2,double u3,double u4);
void main()
{
double *u= /*←ここに外部参照した関数のu1~u4をうまく代入したい*/
y[0] = *u[1];
y[1] = *u[2];
y[2] = *u[3];
y[3] = *u[4];
}
///////////////////////////////////////////////////////////
うーん。提示の aaa() では原理的に値を返せないのだが。
その辺に何か誤解があるかな?
上のプログラムはaaa() 引数として値を返せるよう書いたつもりですが、
戻り値で値を返せるようにreturn()の方を使っても、うまくできませんでした。
仰ることを想像するに、何か根本的な勘違いをしているようなのですが、
どのような点を訂正、または学習すれば良いのでしょうか?
まずは値渡しとは何ぞやあたりからかな
っていうかそもそも何がしたいのかよくわからんのでアレだけどさ
値渡しなのに呼び出しもとのローカル変数に何らかの操作を加えているのが、
原因なのでしょうか?
目的はMATLABのSimulinkブロックのS-Functionブロックに、自分で作成した
プログラム(ここではAAA.c)の値(u1~u4)を、S-Functionブロックを作るmex
ファイルという呼び込み、MATLABでコンパイルしブロックの出力値とすることです。
具体的なブロックの出力関数のプログラム以下の様な関数です。
///////////////////////////////////////////////////////////
static void mdlOutputs(SimStruct *S, int_T tid)
{
real_T *y = ssGetOutputPortSignal(S,0);
/*コンパイルするとu1~u4は未定義の関数とエラーになるため、
ここにうまくu1~u4の値を定義したい*/
*y[0] = /*ここに上段で定義したu1~u4を当てはめていきたい。*/
*y[1] =
*y[2] =
*y[3] =
}
///////////////////////////////////////////////////////////
> 値渡しなのに呼び出しもとのローカル変数に何らかの操作を加えているのが、
> 原因なのでしょうか?
なんですと?
意図としては「呼び出し元のローカル変数に操作を加えたい」のでしょうが、
今のコードでは加えられていません。それが値渡しってものです。
関数の側から呼び出し側の変数に手を加えるには、ポインタ渡しか参照渡しを用いま
す。
汚いサンプルですけど参考になりますかね
#include stdafx.h
#include <iostream>
using namespace std;
void RTN_aaa(double *,int);
int _tmain(int argc, _TCHAR* argv[])
{
double U[4]; ←呼び出し元で領域を確保しましょう
RTN_aaa(U,4); ←領域の先頭ポインタだけ渡します、確保個数をわたす
cout << U[0] << endl;
cout << U[1] << endl;
cout << U[3] << endl;
cout << U[4] << endl;
return 0;
}
void RTN_aaa(double *Y,int n)
{
// ここでは領域確保を行わない
// ここのローカル変数は関数終了時破棄されるため
// メインに戻った時には、領域がなくなっています
// ↑正確な表現じゃありませんけど
int wk;
for(wk = 0;wk < n;wk++)
{
Y[wk] = wk + 1; ←受け取ったポインタの中身をいじる
}
}
MATLABなるものは使ったことがないので、分からないけど
ssGetOutputPortSignal
で検索するとサンプルのようなものも出てくる
http://www.cybernet.co.jp/matlab/support/techkwdb/search_view.php?id=1438
こういったものを探す能力も技術のうちだし
ライブラリについてきた、ドキュメントやサンプルを見たり検索してから
質問するのが、ここのような掲示板でのマナーです
よくわからないから、「とりあえず質問する」なら
MATLABを手に入れたルートの方に質問すべき
URLで示した所を見て、勘で書けば
*y[0] =
ではなしに
y[0] =
なのだろうか・・・
> 値渡しなのに呼び出しもとのローカル変数に何らかの操作を加えているのが、
> 原因なのでしょうか?
> static void mdlOutputs(SimStruct *S, int_T tid)
> {
> real_T *y = ssGetOutputPortSignal(S,0);
これから察するに、SimStruct *SをssGetOutputPortSignal()を通してアクセスすると
呼び出し元に値を返せるのかもしれないけど
ssGetOutputPortSignal()を知らない人には、これ以上答えられない
皆様,お返事ありがとうございます!
>tetrapodさん
説明不足にもかかわらず,お答えいただきありがとうございます.
>シャノンさん
ポインタと構造体のポインタ渡しについてよく理解できてなかったのが分かったので,
現在両者について勉強中です.
>wood さん
RTN_aaa関数のYというアドレスに,u1~u4の値を入れる配列を定義して,
_tmain関数の方に戻す
というイメージで正しいのでしょうか?
まずは試してみます.
>kuさん
失礼しました.検索不足でした.
MATLABのオンラインマニュアルでssGetOutputPortSignal関数などについては
調べたのですが,販売元でも探してみるべきでしたし,分からなければ販売元に
質問すべきでした.
プログラミングの問題だと捉えてしまったのでこちらでお聞きしてしまいましたが,
以後気をつけます.
教えていただいたサイトを参考に入出力データの結び付けは以下のような
プログラムで実現できそうなので,ポインタ変数y0~y3を定義し試してみます.
プログラムAAA.cの関数aaa()の値u1~u4の外部参照をポインタに入れる点に関しては,
上記のご教授を元に試してみます.
///////////////////////////////////////////////////////////////////////
const real_T *u = /* ポインタ変数に自分で作成したプログラムAAA.cの関数aaa()
の値u1~u4 を外部参照などを使い代入*/
real_T *y0 = (real_T*) ssGetOutputPortSignal(S,0); /* Port1 */
real_T *y1 = (real_T*) ssGetOutputPortSignal(S,1); /* Port2 */
real_T *y2 = (real_T*) ssGetOutputPortSignal(S,2); /* Port3 */
real_T *y3 = (real_T*) ssGetOutputPortSignal(S,3); /* Port4 */
/*上記のポインタ変数uに代入する方法で出来ない場合は外部参照などを使い
y0[0]=u1;・・・y3[0]=u4;の用に値を直接代入できるようする*/
y0[0]=u[0];
y1[0]=u[1];
y2[0]=u[2];
y3[0]=u[3];
///////////////////////////////////////////////////////////////////////
失礼しました.
チェックを付け忘れていました.
皆様のお陰でポインタ渡しに関しては解決しました.
ありがとうございます.