良い日です。申し訳ありませんが、おそらく私の問題の定義といくつかの不正確な定義 - 私はちょうどプログラミングで自分自身を試し始めている。それでも、私はすべてを明白に説明するために最善を尽くします。C-Fortran文字列の相互運用性
私はFortranで書かれた数学的なDLLを持っています。
たとえば、機能があります。この関数は、ログファイルの名前をdllに解析して計算を監視するために使用されます。
integer function initLog(
* int_parameter,
* char_parameter,
* char_parameter_length,
* )
*bind(C, name = "initLog");
use, intrinsic :: ISO_C_BINDING;
!DEC$ATTRIBUTES DLLEXPORT::initLog
integer(C_INT), value :: parameter;
character(C_CHAR), intent(in) :: char_parameter(char_parameter_length);
integer(C_INT), value :: char_parameter_length;
...
some_other_variable = char_parameter(1:1)(1:char_parameter_length);
end function;
通常、私はMATLABを使用してdllを処理します。したがって、MATLABから直接関数を呼び出すには.mexファイルを使用する必要があります。 .mexファイルの中には、MATLABとdllの間のインターフェイスを提供するC言語で書かれたインターフェイスコードがあります。例えば、前述の機能のためのCインタフェースは次のとおりです。
int doSmth(const int int_parameter,
const char* char_parameter,
const int char_parameter_length,);
そして私は、機能を得るために、LoadLibrary関数とGetProcAddressなどを使用しています。そして、これはうまく動作します。
しかし、今私はdllを使用するFortranで.exeテストファイルを作成する必要があります。だから、私はDLLをimport.libライブラリにリンクすることによってexeにリンクしなければなりません。この実行可能ファイルの別のオプションは、ログファイルの名前をパラメータとしてコマンドライン経由で取得することです。
program test
use dll_name;
use ifport;
implicit none;
...
integer :: log_init_status;
...
log_init_status = init_log(2, 'logfile.log', len('logfile.log'));
...
end program
このリリースでは正常に動作しますが、「深刻なを返す(664):範囲外:サブストリング終了位置 "だから、最初に私はこのように、単にexeファイル内からログファイルのファイル名を渡そうとしました11 'が文字列長さ' 1 '"よりも大きいです。しかし、最初はこのバグは見つからず、コードを書いていました。これは私が今持っているものです:
program test
use dll_name;
use ifport;
use ISO_C_BINDING;
implicit none;
...
character*255 :: log_flag_char;
integer(C_INT) :: log_flag;
character*255 :: filename;
character(C_CHAR) :: log_filename;
integer(C_INT) :: log_filename_length;
....
call getarg(5, log_flag_char);
read(log_flag_char, *) log_flag;
call getarg(6, log_filename);
log_filename_length = len(log_filename);
log_init_status = analyticsLogInit(log_flag, log_filename, log_filename_length);
...
end program
これはうまくいきましたが、LOG_FILENAMEの唯一の1最初の文字を取った( "C:\ ABCD \ logfile.log" "C" に変換されます)。私が変更した場合
文字(C_CHAR):: log_filename;
に文字(C_CHAR):: LOG_FILENAME(255);
私はlog_filenameの長さが255です(トリムで固定することもできます)。そして、2番目の - mainは再び "severe(664):Out範囲の:部分文字列終了位置 '255'は文字列長 '1'より大きい。
私が変更した場合
log_init_status = analyticsLogInit(log_flag、LOG_FILENAME、 log_filename_length)。
log_init_status = analyticsLogInit(log_flag、C_LOC(LOG_FILENAME)、 log_filename_length)に
。
のように、実際のものとは異なる仮引数型に関するエラーが発生します。
示す664エラーがDLL内のこの行から来ていることを私は自分自身が感じている:
some_other_variable = char_parameter(1:1)(1:char_parameter_length)。
。私は私のexeのような何かを書く必要があります
文字* 255 :: log_filename;
なく
文字:: LOG_FILENAME(255);
しかし、どのように(C_CHAR)を使用して解析することができますか?
私はこれがすべて厄介であり、それはすべて理解の漏れから来ていることを認識していますが、これはプログラミングにおける私の最初の深刻な経験です。
ありがとうございます。確かに、私のためにFortranで研究されるべきことがたくさんあることを理解しています。それでも、文字と(C_CHAR):: log_filename "の構文は、整数と倍精度で動作するので、正常に動作することを確信していました(と私が読んだ記事に書かれていたので) – AntalOvc
悲しいかな、"文字(C_CHAR) "文字(kind = C_CHAR)"は何も与えませんでした。また、今私は "some_other_variable = char_parameter(1:1)(1:char_parameter_length);" "文字(C_CHAR)、intent(in):: char_parameter(char_parameter_length);"として宣言されている場合に機能します。 – AntalOvc