Java JNI C++ ログファイル生成される

このQ&Aのポイント
  • JavaからC++の自作dllを呼び出し、C++dllから外部開発dllの関数を使いハードウェアへコマンドを送信するプログラムでログファイルが生成されるが、その内容が理解できない
  • BSTRの使い方に問題があり、文字化けの問題を解決できないため、現状のプログラムを使用している
  • logファイルの生成に関する問題とBSTRの問題は別物であり、Javaから自作dllを経由して他社dllを使用する構図に問題がある可能性がある
回答を見る
  • ベストアンサー

Java JNI C++ ログファイル生成される

お世話になっております。 以前も何度か似たような質問をさせて頂いたのですが 未だ解決に至りませんので、再度質問させていただきます。 現在、JavaからC++の自作dllを呼び出し、 C++dllから外部開発dllの関数を使いハードウェアへコマンドを送信する。 というプログラムを開発しております。 そこで、プログラムを動かし、終了させると hs_pid...log が生成されます。 ログの内容(一部)↓ # # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x1a212cd2, pid=4716, tid=4332 # # JRE version: 7.0_05-b05 # Java VM: Java HotSpot(TM) Client VM (23.1-b03 mixed mode windows-x86 ) # Problematic frame: # C [PCardRW32.dll+0x22cd2] crwSetLineControl+0x203b2 # # Failed to write core dump. Minidumps are not enabled by default on client versions of Windows # # An error report file with more information is saved as: # C:\eclipse\workspace\ReWriteCard\hs_err_pid4716.log # # If you would like to submit a bug report, please visit: # http://bugreport.sun.com/bugreport/crash.jsp # どうやら、メモリアクセス違反を起こしているみたいなのですが logの内容は理解できません。 そこで、私が開発しましたプログラムを見て頂き、 BSTRの使い方がおかしいとのご指摘を受け、 しばらく調べていたのですが、どうにも改善できません。 C++のプログラム↓ JNI002_API jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj, jint jport) { int port = (int)jport; long int ret = 0; test = crwOpenPort(port, 9600 , "8" , "N"); BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3"); ret = crwSendCommandRR(port,1,1000,1000,0,"DT",":1",2,&s1,&s2,&s3); char* src = (char*)s3; jstring jstr = env->NewStringUTF(src); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); return jstr; } 上記のプログラムのBSTRの使い方が悪いのは、承知致しておりますが WideCharToMultiByte関数を使い、jstrへ変換し、 いかなる方法を試してもJava上で文字化けしますので とりあえず今は現状で使用しております。 そこで試しに、以下のようなプログラムにしてみました これだと、logファイルは生成されません。 JNI002_API jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj, jint jport) { int port = (int)jport; long int ret = 0; /* test = crwOpenPort(port, 9600 , "8" , "N"); BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3"); ret = crwSendCommandRR(port,1,1000,1000,0,"DT",":1",2,&s1,&s2,&s3); char* src = (char*)s3; jstring jstr = env->NewStringUTF(src); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); */ jstring jstr = env->NewStringUTF(""); return jstr; } しかし、以下のようにすると logファイルが生成されます。 JNI002_API jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj, jint jport) { int port = (int)jport; long int ret = 0; test = crwOpenPort(port, 9600 , "8" , "N"); /* BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3"); ret = crwSendCommandRR(port,1,1000,1000,0,"DT",":1",2,&s1,&s2,&s3); char* src = (char*)s3; jstring jstr = env->NewStringUTF(src); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); */ jstring jstr = env->NewStringUTF(""); return jstr; } だとすると、logとBSTRの問題は別物だと判断してもいいんでしょうか また、Java → 自作dll → 他社dll という構図に問題があるんでしょうか ささいなことでも構いません ご教授宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1621/5656)
回答No.4

>さきほどのログは、C++のプログラムをビルドした時のログです。 >私が作成しました、JNI001のプログラムは、DT以外にもメソッド、と言っていいんでしょうか >メソッドがありますので、DT以外の警告だと思います。 それならそれでJava_rewritecard_JNI001_DT以外の関数のコンパイルログを省略する方が・・・ Java_rewritecard_JNI001_DTのコンパイル時の警告を確認したかったのに今まで話にも出てこなかった他の部分のコンパイルログを抜粋されても判断に困るわけですが。 >extern DllImport short int WINAPI crwOpenPort(short int, LONG, LPCSTR, LPCSTR); >extern DllImport short int WINAPI crwSendCommandRR(short int, >short int, >LONG, >LONG, >short int, >LPCTSTR, >LPCTSTR, >short int, >BSTR*, >BSTR*, >BSTR* ); これ書き間違えとかはないですか? crwOpenPortでは引数にLPCSTRが使われていて、crwSendCommandRRでは引数にLPCTSTRが使われているというのは統一性に欠けるというか・・・ とりあえずこれがあってるのであれば少なくともcrwOpenPortの使い方は間違ってないと思いますので、それでjavaがログを出力するということは私が思いつくところでは ・javaがスレッドに割り当てているスタック領域をcrwOpenPortが食いつぶしている ・実はcrwOpenPortは再入不可で、再入された くらいです。 >それとひとつ気になったんですが >C++のプロジェクトのプロパティで、文字セットの設定を >設定なしにしてるんですが、こちらは関係ないでしょうか。 crwSendCommandRRの引数にLPCTSTRがあるので関係すると思いますがプロトタイプ宣言からの推測でしかないので他社性DLLの提供元に確認してみてください。

pokeman-v
質問者

お礼

考えが及んでおりませんでした。 せっかくのご助言、無駄にするような行い 大変申し訳ありません。 関数の書き間違えについては、間違いではないようです。 確認致しましたが、記載どおりでした。 では、 ・javaがスレッドに割り当てているスタック領域をcrwOpenPortが食いつぶしている ・実はcrwOpenPortは再入不可で、再入された こちらの2つの状況を調べてみます。 困り果てておりましたので大変助かりました。 ありがとうございました。

その他の回答 (3)

  • wormhole
  • ベストアンサー率28% (1621/5656)
回答No.3

>正常終了となっていますし、 >引数として渡されるintは、shortを超える数字ではないので、 >良いかなと思い無視しておりましたが、これらの警告は無視できないものなんでしょうか 「引数として渡されるintは、shortを超える数字ではないので、」 こういった理由がある分には無視するのはかまわないです。 無視していないかどうか尋ねたのは、無視してはいけない警告を無視してないかどうかなので。 ところでこのコンパイルのログは何をコンパイルしたものなんでしょうか? 質問文に書かれているJava_rewritecard_JNI001_DT()のコンパイルログにしては >jstring jstr = env->NewStringUTF(src); 関数内でenvは使われているのに >1>JNI002.cpp(16): warning C4100: 'env' : 引数は関数の本体部で 1 度も参照されません。 という警告が出てるのが不思議なんですけど。 もし可能であれば crwOpenPort(), crwSendCommandRR() のプロトタイプ宣言教えていただけませんか?

pokeman-v
質問者

補足

ご回答ありがとうございます。 さきほどのログは、C++のプログラムをビルドした時のログです。 私が作成しました、JNI001のプログラムは、DT以外にもメソッド、と言っていいんでしょうか メソッドがありますので、DT以外の警告だと思います。 プロトタイプ宣言、意味をはき違えてましたら申し訳ないですが こちらでよろしいでしょうか。 extern DllImport short int WINAPI crwOpenPort(short int, LONG, LPCSTR, LPCSTR); extern DllImport short int WINAPI crwSendCommandRR(short int, short int, LONG, LONG, short int, LPCTSTR, LPCTSTR, short int, BSTR*, BSTR*, BSTR* ); それとひとつ気になったんですが C++のプロジェクトのプロパティで、文字セットの設定を 設定なしにしてるんですが、こちらは関係ないでしょうか。 お手数おかけしますが、宜しくお願いいたします。

  • wormhole
  • ベストアンサー率28% (1621/5656)
回答No.2

>関数の使い方 >ということに関して、dllを開発した会社へプログラムを見て頂き、 >問い合わせを行ったところ >BSTRの使い方がおかしいとの指摘を頂きました。 確かにBSTRの使い方におかしいところはあると思うんですが(私はBSTRは使ったことないのでMSDNにあるドキュメントを読んだだけですが) http://msdn.microsoft.com/ja-jp/library/xda6xzx7%28v=vs.80%29.aspx ただ、いくらBSTRの使い方がおかしいにしてもワイド文字列が設定されるところにマルチバイト文字列が設定されて返ってきてる事もおかしいんです。 他にも気になってる事があって >ret = crwSendCommandRR(port,1,1000,1000,0,"DT",":1",2,&s1,&s2,&s3); 第9~11引数にはBSTRのポインタを要求していながら第6, 第7引数がマルチバイト文字列というのも不思議な気がしてます。 もしかして他社製DLLを使用するためのヘッダファイルをインクルードしていなかったり、コンパイル時の警告を無視していたりしませんか?

pokeman-v
質問者

補足

ご回答ありがとうございます。 さきほど、C++のプログラムを確認いたしました。 インクルードはできております。 インクルードしていなかったら、関数を指定するときに、エラーが出ますので できていると思うんですが、 コンパイル時の警告に関しては さきほど、C++の警告レベルがレベル3だったのを、レベル4に変えて コンパイルしなおしてみました。 以下が実行結果の出力です。 1>------ ビルド開始: プロジェクト: JNI002, 構成: Release Win32 ------ 1> stdafx.cpp 1> dllmain.cpp 1>dllmain.cpp(7): warning C4100: 'lpReserved' : 引数は関数の本体部で 1 度も参照されません。 1>dllmain.cpp(4): warning C4100: 'hModule' : 引数は関数の本体部で 1 度も参照されません。 1> JNI002.cpp 1>JNI002.cpp(16): warning C4100: 'obj' : 引数は関数の本体部で 1 度も参照されません。 1>JNI002.cpp(16): warning C4100: 'env' : 引数は関数の本体部で 1 度も参照されません。 1>JNI002.cpp(53): warning C4244: '引数' : 'int' から 'short' への変換です。データが失われる可能性があります。 ・ 文字数制限のため割愛致します ・ 場所が違うのみで、エラー内容は同じです(割愛分56行) ・ 1>JNI002.cpp(425): warning C4100: 'obj' : 引数は関数の本体部で 1 度も参照されません。 1>JNI002.cpp(425): warning C4100: 'env' : 引数は関数の本体部で 1 度も参照されません。 1> ライブラリ C:\username\username\Documents\Visual Studio 2010\Projects\JNI002\Release\JNI002.lib とオブジェクト C:\username\username\Documents\Visual Studio 2010\Projects\JNI002\Release\JNI002.exp を作成中 1> コード生成しています。 1> コード生成が終了しました。 1> JNI002.vcxproj -> C:\username\username\Documents\Visual Studio 2010\Projects\JNI002\Release\JNI002.dll ========== ビルド: 1 正常終了、0 失敗、0 更新不要、0 スキップ ========== そして、これが完了した後 プログラム C:\パス・・・\JNI002.dllを開始できません というポップアップが出てOKボタンをクリックします。 正常終了となっていますし、 引数として渡されるintは、shortを超える数字ではないので、 良いかなと思い無視しておりましたが、これらの警告は無視できないものなんでしょうか

  • wormhole
  • ベストアンサー率28% (1621/5656)
回答No.1

>そこで、私が開発しましたプログラムを見て頂き、 >BSTRの使い方がおかしいとのご指摘を受け、 >しばらく調べていたのですが、どうにも改善できません。 何か勘違いされてるようなんですが私は「BSTRの使い方がおかしい」とはいってませんよ? 「他社製DLLの使い方を間違ってないか確認した方がよいと思いますよ」と書いてたはずですが。 少なくともcrwSendCommandRR()の第9~11引数はBSTRへのポインタを要求するにしてはマルチバイト文字列へのアドレスが格納されて返ってくる事がおかしいんです(BSTRが扱うのはワイド文字列) で、crwSendCommandRR()をはじめとする他社製DLLが提供している関数の使い方が正しいのか間違ってるのかは、その仕様を知らない私らには判断できません。 なのでその他社製DLLの提供元に関数の使い方を確認することをお勧めします(以前からいってる)。

pokeman-v
質問者

補足

説明不足でありました。 お気を悪くされたようですね。 大変申し訳ないです。 wormholeさんから指摘して頂いた 関数の使い方 ということに関して、dllを開発した会社へプログラムを見て頂き、 問い合わせを行ったところ BSTRの使い方がおかしいとの指摘を頂きました。 そのほかにも、教えてGooにて、wormholeさんではない方から、 BSTRの使い方がおかしいと指摘をいただきました。 説明不足、大変申し訳ありません

関連するQ&A

  • JNI 戻り値の渡し方について

    javaからCのdllを呼出すJNIを作っています。 やりたい事は ・C側で実行した結果がchar[256]に設定され、戻り値としてjava側に渡される。 ・java側でその中身を編集する ですが、java側で例外が発生します。 jcharArrayと言う型に入れさえすれば良いと思ってたのですが・・・ char[]をjava側で見る&編集する方法をどなたかご教授ください・・・。 よろしくお願いします。 ----------jnitest.dll---------- #include "stdafx.h" #include "../../JNI_test.h" #include <Windows.h> #include <stdio.h> #ifdef _MANAGED #pragma managed(push, off) #endif BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { return TRUE; } #ifdef _MANAGED #pragma managed(pop) #endif JNIEXPORT jcharArray JNICALL Java_JNI_1test_getScreenData(JNIEnv *env, jobject obj){ LONG ret; LONG id; char buff[256]; LPVOID lpvoid; DWORD len = 0; memset(buff,0x00,sizeof(buff)); lpvoid = buff; len = sizeof(buff); ~ここでbuffに値を設定する~ jcharArray result = (jcharArray)buff; return result; } ----------JNI_test.java---------- public class JNI_test { public native char[] getScreenData(); static{ System.loadLibrary("jnitest"); } public static void main(String[] args) { JNI_test jniObj = new JNI_test(); char[] kekka = jniObj.getScreenData(); System.out.println("出力内容:"+kekka);←ここで例外発生。 } }

  • JavaとObjective-c間でJNIエラー

    JavaとObjective-c間でJNIを使用してGUIのアプリケーション連携を行いたいのですが エラーになってしまいます。 アプリケーションの起動をNSApplicationMain関数を使用してしようとしてるのですが、 JNIの関数では使用できないのでしょうか? 一部抜粋ですが、以下のように呼び出しています。 また、このように連携を行いたい場合、どのようにするべきでしょうか? ご教授ください。 JNIEXPORT void JNICALL Java_JniApp_start (JNIEnv *env, jobject this) { int argc = 0; char *argv[0]; NSApplicationMain(argc, (const char**)argv); } こちらをJava側で呼び出すとエラーとなります。 エラー内容は以下になります。 java[1646:1303] No Info.plist file in application bundle or no NSPrincipalClass in the Info.plist file, exiting

  • C++ ハードウェアから文字列受信 文字化け

    C++初心者のため大変困っております。 正直に申し上げますと、だれか助けて下さい。 どなたかご教授宜しくお願いいたします。 まずは簡単な仕様から JavaでC++を呼び出し、C++でハードウェアを動かします ハードウェアから文字列を受け取り、Javaに返すというプログラムを開発しております。 以下に現在の状況を示します ・C++のプロジェクト→プロパティ→マルチバイト文字を使用する にチェックを入れました ・ソースです↓ 以下をJavaから呼び出し、戻り値を取得しています printfがたくさんありますが、文字列をチェックするためのものです。ご了承ください。 JNIEXPORT jstring JNICALL Java_rewritecard_JNI001_DT(JNIEnv *env, jobject obj) { BSTR s1 = ::SysAllocString(L"s1"); BSTR s2 = ::SysAllocString(L"s2"); BSTR s3 = ::SysAllocString(L"s3");     //ハードウェアにコマンドを送信する関数です     //レスポンスが、s3のアドレスに格納されます。      crwSendCommandRR(           4,        //ポート番号           1,        //ポーリングフラグ           10000,     //タイマー           0,        //タイマー           1,        //DSR信号線チェックフラグ           "DT",     //コマンドコード           ":1",      //ハードウェアに送信するパラメータ           2,        //パラメータの長さ           &s1,      //レスポンスを格納するアドレス 1            &s2,      //レスポンスを格納するアドレス 2           &s3      //レスポンスを格納するアドレス 3    ); printf("s3:\n", s3); printf("s3:%d\n", s3); printf("s3:%x\n", s3); printf("s3:%s\n", s3); //BSTR を char に変換---------------------------------------------- char buf[64]=""; WideCharToMultiByte( CP_ACP,           // コードページ ANSI コードページ WC_NO_BEST_FIT_CHARS,// 処理速度とマッピング方法を決定するフラグ (OLECHAR*)s3,      // ワイド文字列のアドレス -1,             // ワイド文字列の文字数 buf,            // 新しい文字列を受け取るバッファのアドレス sizeof(buf) - 1,    // 新しい文字列を受け取るバッファのサイズ NULL,          // マップできない文字の既定値のアドレス NULL           // 既定の文字を使ったときにセットするフラグのアドレス ); int len = strlen(buf); for(int i = 0; i < len; i++) { printf("\nbuf:", buf[i]); printf("\nbuf:%d", buf[i]); printf("\nbuf:%x", buf[i]); } char* src = buf; printf("\nsrc:",src); printf("\nsrc:%d",src); printf("\nsrc:%x",src); printf("\nsrc:%s",src); jstring jstr = env->NewStringUTF(src); printf("\njstr:", jstr); printf("\njstr:%d", jstr); printf("\njstr:%x", jstr); printf("\njstr:%s", jstr); ::SysFreeString(s1); ::SysFreeString(s2); ::SysFreeString(s3); return jstr; } ・実行結果 Java側 ?????   //?になります。本来なら 1:19900309 C++側  s3: s3:3150196 s3:301174 s3:1:19900309 c: c:3150196 c:301174 c:1:19900309 buf: buf:63 buf:3f buf: buf:63 buf:3f buf: buf:63 buf:3f buf: buf:63 buf:3f src: src:71756992 src:446ecc0 src:???? jstr: jstr:65927816 jstr:3edfa88 jstr:Pァ$@ヌ#@ヌ#@ヌ#(CO どうもWideCharToMultiByteの使い方が悪いのかと思うんですが C++初心者のため、どこがどうおかしいのか答えが出せずにおります 他に何かございましたら補足致しますので宜しくお願い致します。

  • JNIについて

    JNIを使ったJavaコードの実行ができず困っています. 【Javaのコード】 public class HelloWorldJNI { static { System.loadLibrary("HelloWorldJNI"); } public native void sayHelloWorld(); public static void main(String[] args) { HelloWorldJNI hello = new HelloWorldJNI(); System.out.println("テスト"); hello.sayHelloWorld(); } } 【Cのコード】 #include "HelloWorldJNI.h" int main(int argc, char * argv[]) { return 0; } JNIEXPORT void JNICALL Java_HelloWorldJNI_sayHelloWorld (JNIEnv *env, jobject obj ) { printf("Hello JNI World\n"); return; } 【Cのコンパイラ】 Microsoft Platform SDK for Windows Server 2003で, WindowsXP x64 Buid Environmentを使って,↓のようなバッチファイルを 実行しています. (OSは,WindowsXPのx64edition SP2です.) コンパイル・リンク中にエラーは出ません. 【ビルド】 echo off set JNI="C:\Program Files\Java\jdk1.6.0_07\include" set JNI1=%JNI%\win32 set OUTPUTDIR=. cl /nologo /c /I%JNI% /I%JNI1% /I. /LD /Zi /Od HelloWorldJNI.c LINK /nologo /NODEFAULTLIB /OPT:NOREF /out:HelloWorldJNI.dll HelloWorldJNI.obj bufferoverflowu.lib oldnames.lib kernel32.lib user32.lib netapi32.lib advapi32.lib gdi32.lib comdlg32.lib comctl32.lib wsock32.lib libcmtd.lib 【実行結果】 ↓こんなエラーになります. C:\WORK\>"C:\Program Files\Java\jre1.6.0_07\bin\java.ex e" HelloWorldJNI テスト # # An unexpected error has been detected by Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000000001c0e8, pid=3864, t id=2528 # # Java VM: Java HotSpot(TM) 64-Bit Server VM (10.0-b23 mixed mode windows-amd64) # Problematic frame: # C 0x000000000001c0e8 # # An error report file with more information is saved as: # C:\work\hs_err_pid3864.log # # If you would like to submit a bug report, please visit: # http://java.sun.com/webapps/bugreport/crash.jsp # The crash happened outside the Java Virtual Machine in native code. # See problematic frame for where to report the bug. # 【質問】 原因となっていることや確認すべきことをご指摘頂ける方, いらっしゃいませんでしょうか.

    • ベストアンサー
    • Java
  • C++DLLからC#へのコールバックに文字列の配列を渡したい

    教えてください! C++のアンマネージドDLLから、複数のファイル名(文字列)をC#に渡したいです。 ステップとしては、 C#から、C++のDLLの関数を最初に呼んで、コールバック関数を渡しています。 次に、DLLからコールバック関数を呼ぶ時に、複数のファイル名を渡したいです。 以下のコードを動かすと、、 C++からは2つ渡しているつもりなのに、 C#ではfilesがサイズ1のString配列として引数に入ってきます。 なぜでしょう? またどうすればC#から複数受け取れるでしょうか? 教えてください! C# public delegate int StringArrayCallback(String[] files); // C# -> C++ public static int start() { StringArrayCallback cb = new StringArrayCallback(onReceivedFiles); int ret = start(cb); return ret; } // C++ -> C# callback public static int onReceivedFiles(String[] files) { return 1; } C++コード typedef int (__stdcall *OnReceivedFilesProc )(char**); int start( OnReceivedFilesProc callback ) { std::string message1_ = "from C++1"; std::string message2_ = "from C++2"; char* messages_[2] = { (char*)message1_.c_str(), (char*)message2_.c_str() }; int ret_ = callback(messages_); std::cout << "[from c#]" << ret_; }

  • C言語 説明文

    C言語(文字列のコピーについて) /* 文字列のコピーを行う関数の実現例 動作原理のコメントを書き入れる */ #include <stdio.h> /*-----文字列のコピー(1)-----*/ char *scpy1 (char *d, const char *s) { int i = 0; while ((d[i] = s[i]) != '\0') { i++; } return(d); } /*-----文字列のコピー(2)-----*/ char *scpy2 (char *d, const char *s) { char *p = d; while ((*d = *s) != '\0') { d++; s++; } return(p); } /*-----文字列のコピー(3)-----*/ char *scpy3 (char *d, const char *s) { char *p = d; while ((*d++ = *s++) != '\0') { ; } return(p); } /*-----文字列のコピー(4)-----*/ char *scpy4 (char *d, const char *s) { char *p = d; while (*d++ = *s++) { ; } return(p); } int main(void) { char astr[] = "ABC"; char bstr[8], cstr[8], dstr[8],estr[8]; scpy1 (bstr, astr); scpy2 (cstr, astr); scpy3 (dstr, astr); scpy4 (estr, astr); printf("astr = %s\n" , astr); printf("bstr = %s\n" , bstr); printf("cstr = %s\n" , cstr); printf("dstr = %s\n" , dstr); printf("estr = %s\n" , estr); return (0); } ----------------------- このプログラムに、この行で何をやっているのかわかるように 一言くらいの説明文を入れる問題です。 ところどころはわかるのですが、わからないところの方が多いです。 プログラムが長くて大変かとは思いますが、どうかよろしくお願いいたします。 このプログラム自体はちゃんとコンパイルでき、実行もできたので おそらく間違いないと思います。

  • C# ポインタ アクセス違反

    お世話になります たびたび申し訳ないですが C#でDLLとリンクするプログラムを作成してます。 その時に、DLLの関数へポインタを渡すんですが おそらくその時に、アクセス違反が起きてます。 以下ソースです。 引数として渡されるStringには数字が入ってます。 unsafe public short import(String s) { short ret = 999; short no; uint brate; char bit = '8'; char Parity = 'N'; no = short.Parse(s); brate = uint.Parse("9600"); // 問題の箇所 ret = dllImport(no, brate, &bit, &Parity); return ret; } これは私の予想なのですが 上記で宣言した char bit、 char Parity がpublicではないので DLL内で参照するときに、エラーが出てしまうのではないかと考えて char bit、 char Parity をどうにかpublicにできないか試したのですが 調べてもどうも方法がわからず、相談させていただきました。 そもそもpublicにしたところで、エラーが出なくなるか不明ですし 根本の原因がわかりません。 少ない情報で大変恐縮ですが お分かりになる方、ご教授お願い致します。

  • C++でのDLL利用について

    http://1c3.world.coocan.jp/wiki/index.php?%A5%B3%A5%F3%A5%C8%A5%ED%A1%BC%A5%EBDLL%A4%F2%BA%EE%A4%ED%A4%A6#p92ca3d9 こちらのページで公開されている、pc-op-rs1-control.dllを使って、 自作プログラムを製作しようと考えています。 開発環境はVisual C++です。 上記ページのAPIリファレンスを見ると、 例えばドライバをオープンする関数は PCOPRS1CONTROL_RET Open(int port_no) というように書かれています。 そこで私の書いてみたプログラムは以下のとおりです。 #include <Windows.h> typedef PCOPRS1CONTROL_RET(WINAPI *OPEN)(int port_no); int _tmain(int argc, _TCHAR* argv[]) { HINSTANCE lib; lib = LoadLibrary(TEXT("pc-op-rs1-control.dll")); //dllはEXEファイルと同じディレクトリに配置 if (lib == NULL){ // ここにはエラーメッセージを入力してください printf("dll呼び出しエラー\n"); return -1; } OPEN Open = (OPEN)GetProcAddress(lib,"open"); printf("実行開始"); PCOPRS1CONTROL_RET open = Open(7); if(open == PCOPRS1CONTROL_RET_OK) printf("Open成功"); bool End = FreeLibrary(lib); return 0; } こうすると、 PCOPRS1CONTROL_RETという型が宣言されていない(?)ので、 コンパイルが通りません。 試しに typedef void(WINAPI *OPEN)(int port_no); としてみたりすると、 Open()を実行した瞬間死にます。 pc-op-rs1-control.dllのソースを見ても、 PCOPRS1CONTROL_RET型についての明記が見当たらないような気がするのですが、 どうしたらいいのでしょうか?

  • 文章中から特定の文字列を抜き出すプログラムについて C言語

    log.txtの文章からIPを抜き出しip.txtに書き込むというものです。log.txtの文章は基本的にfrom IP:port の順です。しかし文章中にfromがないとip.txtで空欄になってしまいます。 例192.168.1.100  192.168.1.110 理想はfromがない行はなにも追加せず次に移りたいのですがどうすればいいでしょうか? 例192.168.1.120 192.168.1.130 192.168.1.140 void addLine(const char*,FILE*); char *getFromIP(const char*,char*); int main() { FILE *pFileA = fopen("log.txt","rt"); char buff[256]; if(pFileA){ FILE *pFileB = fopen("ip.txt","wt"); if(pFileB){ for(;fgets(buff,256,pFileA) != NULL;){ char buff2[32] = {'\0'}; addLine(getFromIP(buff,buff2),pFileB); } fclose(pFileB); } fclose(pFileA); } return 0; } char *getFromIP(const char *line, char *buff) {  char *src, *dst;        src = strstr(line, "from");  if(src==NULL) { return buff; }   src += 4;            dst = buff;          while(1) {   if(isspace(*src))  {    src++;    continue;          }   else break;         }                    while(1) {   *dst = *src;          if(*dst == ':')        {    *dst = '\0';          break;           }   if(*dst == '\0')       {   break;           }  dst++;            src++;           }  return buff;         } void addLine(const char *str,FILE *pFile){ char buff[1024]; sprintf(buff,"%s\n",str); fputs(buff,pFile); }

  • C言語のこれを日本語にすると

    お世話になっております。 いまC言語のプログラムを勉強しているのですが こちらの意味が分かりません。 //使用変数の定義 int port; char s_port[7]; これを訳すとどういう意味になるのでしょうか? またかっこの7はどういう意味でしょうか? あわせてご回答宜しく御願いいたします。

専門家に質問してみよう