2015-12-18 20 views
6

私はCOBOLプログラマーです。私の最新プロジェクトは、COBOLアプリケーションをSQLite3データベースに接続することです。COBOLでSQLiteコールバックを書く方法

私はthis guideを追っており、その解決策は、私は私のCOBOLアプリケーションで必要となる、まさにです。データの作成、接続、挿入、データベースのクローズに成功しましたが、データベースからデータを選択しようとすると問題が発生します。

このチュートリアルでは、二重ポインタを使用したコールバックを使用しています。

static int callback(void *NotUsed, int argc, char **argv, char **azColName){ 
    int i; 
    for(i=0; i<argc; i++){ 
     printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL"); 
    } 
    printf("\n"); 
    return 0; 
} 

WORKING-STORAGE SECTION. 
    *----------------------------------------------------------------* 

    01 sqlite3-db   pointer. 
    01 err_msg   pointer. 
    01 sqlite    pointer. 
    01 res    pointer. 

    01 notused   pointer. 
    01 argc    pic 99 comp-5. 
    01 argv    pointer. 
    01 azColName   pointer. 
    01 Writefunction-Ptr procedure-pointer. 

    procedure division. 
      set Writefunction-Ptr to entry "sqlite-callback". 

      *>Random code. 

      call "sqlite3_exec" using 
      by value sqlite3-db 
      by reference sqlQuery 
      by value Writefunction-Ptr 
      by value 0 
      by reference err_msg 
      returning rc 
      end-call 

      *>Random code. 

    stop run. 

    entry "sqlite-callback" using 
      by value notused 
      by value argc 
      by reference argv 
      by reference azColName. 

     display argc 

     goback. 
    Entry-Termination. 
それは、データベースから返される行数と呼ばれ、整数ARGCは、列の数が含まれているため、コールバックが機能

以下れるCOBOLで私のソリューションテーブルが含まれています。

質問がある:COBOLで

ダブルポインタ、それらがどのように表現されていますか?私のソリューションでは、私はポインタを宣言し、ポインタ上の "参照"でコールバックを呼び出します。これがCOBOLでダブルポインタを表現する正しい方法であるかどうか分かりませんか?

にはどうすればいいazColNameとargvの内容を表示しない、とするだけでなく、メモリアドレスポインタのポイント?

私は今、一連のアドレスを使用しようとしましたホーブが、私はまだそれが仕事を得るドント。私が逃した何かでなければならない。現時点では私のソリューションは、次のようになります。

WORKING-STORAGE SECTION. 
01 argv pointer. 

Linkage Section. 
01 link-area pic x. 

procedure division using link-area. 

*> RANDOM CODE 

    set address of link-area to argv 
    call "sqlite3_exec" using 
     by value sqlite3-db 
     by reference z"SELECT * FROM Cars" 
     by value Writefunction-Ptr 
     by value 0 
     by reference err_msg 
     returning rc 
     end-call 

*> RANDOM CODE 


entry "sqlite-callback" using 
    by value notused 
    by value argc 
    by reference argv 
    by reference azColName. 

    display argc. 

    if address of link-area not = null 
    display "Contents of new argv: " link-area 
    else 
    display "empty" 
    end-if 

    goback. 

Entry-Termination. 

私が得る結果は、ステートメントが常に偽であるので、「空」の文字列が表示されている場合ということです。しかし、まだargcはテーブルの列数に設定されています。

作業溶液:

WORKING-STORAGE SECTION. 

    01 argv. 
     03 firstColumn pointer. 
     03 secondColumn pointer. 
     03 thirdColumn pointer. 

    01 azColName   pointer. 
    01 argc    pic 99 comp-5. 
    01 notused   pointer. 

    01 Writefunction-Ptr procedure-pointer. 

    *----------------------------------------------------------------- 
    Linkage Section. 

    01 Cars_Id  pic 9(2). 
    01 Cars_Name  pic X(20). 
    01 Cars_Price pic 9(10). 
    /----------------------------------------------------------------- 
    procedure division. 

    //code  

    set Writefunction-Ptr to entry "sqlite-callback". 

      initialize sqlQuery 
      move z"SELECT * FROM Cars;" to sqlQuery 


      call "sqlite3_exec" using 
      by value sqlite3-db 
      by reference sqlQuery 
      by value Writefunction-Ptr 
      by value 0 
      by reference err_msg 
      returning rc 
      end-call 

    //code 

    stop run. 



    entry "sqlite-callback" using 
      by value notused 
      by value argc 
      by reference argv 
      by reference azColName. 

     set address of Cars_Id to firstColumn 
     set address of Cars_Name to secondColumn 
     set address of Cars_Price to thirdColumn 


     display Cars_Id "|" Cars_Name "|" Cars_Price 

     goback. 
    Entry-Termination. 
+1

どのCOBOLを使用していますか?リンクセクションなしでコンパイルできますか? SET ADDRESS OF x TOをあなたのポインターに見てください。ここで、xはリンケージ・セクションで定義されています。サイズとタイプはあなたが望むものです。これにより、ポインターが指すデータにアクセスすることができます。 –

+0

MarcusはMicroFocus ServerExpressコンパイラを使用しています。 – Anders

答えて

3

私たちは本当にあなたが使用しているコンパイラを知る必要があります。

SET文の場所が間違っています。 argvは、ENTRYが呼び出されたときにのみアドレスを持ちます。エントリが呼び出される前に、それはバイナリのゼロ、または予測不可能なごみです。

あなたはENTRY後にSETを移動する場合は、その後、LINK-AREAの値を使用することができるはずです。 argvはまだアドレスに過ぎませんが、LINK-AREA(より良い名前を付けてください)はそのアドレスを指しているので、argvを定義する必要があるのでLINK-AREAを定義してから実際のコンテンツを取得することができますargvの。


BY REFERENCEを使用する場合、コンパイラは、データ項目のアドレスをポインタを渡すためのコードを生成します。

PROCEDURE DIVISION USINGまたはENTRY USINGの項目もBY REFERENCEである必要があり、コンパイラは、渡されたアドレスにリンクセクションの定義をマップするコードを生成します。

あなたがBY CONTENTを使用する場合、これは似ていますが、コンパイラは、プログラム内のデータのコピーを取り、ポインタの代わりに参照を渡します。BY REFERENCEとして依然として定義されている手順部または入場部の使用について。

BY VALUEの場合、コンパイラは、標準で指定されたものまたは実際のコンパイラで標準に拡張されたもののいずれかに制限がありますが、実際の値を「渡します」。 PROCEDURE DIVISIONまたはENTRYのUSINGにはBY VALUEも指定する必要があります。

すべてのUSINGでBY REFERENCE/CONTENT/VALUEが伝播されますが、すべてが同じでBY BY REFERENCEが必要な場合はBYを指定する必要はありません。デフォルトです。

POINTERUSAGE POINTER)を「合格」すると、SET ADDRESS OFを使用して指し示すデータにアクセスできます。 SET ADDRESS OF項目はLINKAGE SECTIONである必要があります。

SET ADDRESS OFで暗黙ポインタを使用することもできます。アドレスにbのアドレスを設定すると、リンクセクションにマップされたアドレスが、プログラムのDATA DIVISIONFILE SECTION以外の任意のセクション)のどこかで定義されている項目のアドレスbに変更されます。

POINTERが指すデータを表示する場合は、正しいサイズとタイプの項目を定義し、SET ADDRESS OF item TOポインタ名を使用します。

POINTERはもちろん、単純なデータ項目またはグループデータ項目(構造)を指すことができます。

リンクセクションのすべての項目は、参照する前にアドレスが必要です。 USING上のものには、コンパイラによるアドレス可能性が与えられます(そして、コンパイラは、正しいアドレス数/項目数が渡されたとみなします)。他のすべてのリンクセクション項目は、SET ADDRESS OFによって設定されたアドレス可能性を持っていなければなりません。また、USING内のアドレスCALLを渡して、CALLedプログラムがアドレスを設定していなければなりません。

+0

ありがとうございました。コールバックは今動作します。 –

関連する問題