Mar*_*erg 6 sqlite cobol double-pointer
我是COBOL程序员,我的最新项目是将COBOL应用程序连接到SQLite3数据库.
我一直在关注本指南,他们的解决方案正是我在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;
}
Run Code Online (Sandbox Code Playgroud)
我在COBOL中的解决方案如下
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.
Run Code Online (Sandbox Code Playgroud)
回调有效,因为它被称为从数据库返回的行数,而整数argc包含表包含的列数.
问题是:
COBOL中的双指针,它们是如何表示的?在我的解决方案中,我声明了一个指针,并在指针上使用"by reference"调用回调.不知道这是否是在COBOL中表示双指针的正确方法?
如何显示azColName和argv的内容,而不仅仅是指针指向的内存地址?
我现在试图使用SET ADDRESS OF,但我仍然没有让它工作.一定是我错过的东西.我此刻的解决方案如下:
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.
Run Code Online (Sandbox Code Playgroud)
我得到的结果是if语句总是false,因此显示字符串"empty".但仍然将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.
Run Code Online (Sandbox Code Playgroud)
我们确实需要了解您正在使用的编译器。
您的 SET 语句位置错误。argv仅在被调用时才有地址ENTRY。在调用该条目之前,它将是二进制零,或者一些不可预测的垃圾。
如果将 SET 移至 ENTRY 之后,则应该能够使用 LINK-AREA 的值。argv仍然只是一个地址,但是 LINK-AREA (请给它一个更好的名称)将指向该地址,因此应将其定义为 argv ,然后可以使用 LINK-AREA 来获取 的实际内容argv。
使用时,BY REFERENCE编译器生成代码来传递带有数据项地址的指针。
在PROCEDURE DIVISION USING或ENTRY USING项上也应该是 BY REFERENCE,编译器会生成代码以将 LINKAGE SECTION 定义映射到传递的地址。
如果您使用 ,则情况类似BY CONTENT,但编译器会获取程序中数据的副本并传递引用该数据的指针。在使用仍定义为 BY REFERENCE 的 PROCEDURE DIVISION 或 ENTRY 时。
尽管存在BY VALUE限制,但编译器“传递”实际值,无论是标准中指定的限制还是实际编译器对标准的扩展。PROCEDURE DIVISION 或 ENTRY 的 USING 也应指定 BY VALUE。
在所有 USING 上,都会传播 BY REFERENCE/CONTENT/VALUE,如果所有内容都相同并且您想要 BY REFERENCE,则根本不需要指定 BY,这是默认值。
如果您“传递” POINTER( USAGE POINTER) 那么您可以访问使用 指向的数据SET ADDRESS OF。项目的设置地址必须位于LINKAGE SECTION.
您还可以将隐式指针与 SET ADDRESS OF 一起使用。SET ADDRESS OF a TO ADDRESS OF b 会将 LINKAGE SECTION 中映射的地址更改为 b 的地址,b 是在程序中某处定义的项DATA DIVISION(除 之外的任何 SECTION FILE SECTION)。
如果要查看 POINTER 指向的数据,请定义一个具有正确大小和类型的项,并使用 SET ADDRESS OF item TO point-name。
POINTER当然可以指向一个简单的数据项或一组数据项(结构)。
LINKAGE SECTION 中的所有项目在被引用之前都必须有一个地址。USING 上的那些由编译器赋予可寻址性(并且编译器假设传递了正确数量的地址/项)。所有其他 LINKAGE SECTION 项必须具有通过 SET ADDRESS OF 或通过在使用 a 时传递 ADDRESS OFCALL并使被调用程序设置地址而建立的可寻址性。
| 归档时间: |
|
| 查看次数: |
515 次 |
| 最近记录: |