PRO*C 解决可变参数函数编译错误问题PCC-S-02322 PCC-S-02201 PCC-S-02015

5 篇文章 0 订阅
3 篇文章 0 订阅
此次问题总结

1.工程中用到##拼接宏,该宏proc无法识别(文档记载)-头文件进行重新整合,后续样例。
2.typedef int hhh_t 该在parse=none时无法识别(根据调整选项时的经验)-选项使用parse=full默认的好像也是这个。
3.除一些可以识别的系统头文件,加入proc预编译会core-头文件需要重新整合。
4.找不到自定义相关文件的头,加入选项include={…/inc1/,…/include2/}即可,内容为自定义文件的目录路径
5.找不到系统头文件,加入选项sys_include={/usr/include/}即可,内容为对应系统文件头的目录路径。该情况加入头以后仍无法解决,需判断是否需要该系统头文件,是否需要将相关无用的头文件交予gcc而不是proc-即ORA_PROC宏的使用

其他以前遇到的问题

1.程序没有使用多线程,结果编译参数threads=yes 编译错误-解决方法去掉该编译选项即可

proc工具官方文档地址

https://docs.oracle.com/database/121/LNPCC/toc.htm

此次解决过程

首先一开始编译按照C语言的头文件规则把所有的头都加进去了,然后再proc的预编译解阶段core掉了,生成一个core文件,没办法找出原因,然后百度和必应查找都没有找到原因,网上各种解决方法都是sys_include选项修改增加,全部无法解决我遇到的问题。我的pc文件有接近20w行。
里面用到静态嵌入sql,动态嵌入sql。在我怀疑是代码问题的时候,我把代码从上到下由1个函数到6个函数进行预编译,发现在进行有个动态嵌入sql的时候出现了问题。把改函数单独拿出来也有问题。
期间,搜索到有人遇到过文件名太长的错误,造成proc编译core掉
https://www.cnblogs.com/kingstarer/p/12079989.html
1.猜测头文件路径问题,修改各种编译选项并适配编译路径仍无法解决,排除该问题。
2.猜测程序嵌入部分代码段问题,通过把该函数删掉只剩下宿主变量声明的时候还是编译异常,排除代码段问题。
3.猜测头文件#include 问题,重新阅读oracle提供的预编译文档,其中有记路可识别的和不可识别的。将可以识别的包含,自定义的简单宏定义在mymacrodef.h文件中

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"mymacrodef.h"

在其他头文件里面定义了宏表示宿主变量的数组大小 结果没有#include 然后报告

PCC-S-02322 ,found undefine identifier
Semantic error at line xxxx,column xxx,file xx.pc

文件不存在或者不在指定的proc默认搜索路径下面-部分文件缺失造成-路径顺序有优先级

PCC-S-02015, unable to open include file
Error at line 51, column 11 in file /usr/include/wchar.h
#include <stddef.h>
more  $ORACLE_HOME/precomp/admin/pcscfg.cfg
find / -name  stddef.h 2>/dev/null

编译指定特定搜索路径

sys_include={$(ORACLE_HOME)/precomp/public,加入无缺失的}

我把带有相关宏定义头带进去
然后 又

PCC-S-02201,Encountered the symbol "size_t" when expecting one of  the  following  :
char,const,double  等等

我去看了一下相关头 ,里面还有一些pthread.h sys/call.h等等 我猜想 PROC 阅读能力不高端 有些宏定义无法识别(详细oracle的嵌入式SQL) 而且一些类型名被重命名 ,所以出错,
编译选项 parse=full 才能通过,因此我把头分开 能识别的宏定义和类型 弄到pc文件里面 不能识别的用于后续gcc编译的声明放入
#ifndef ORA_PROC
#include"其他"
#endif

样例详情
#文件树结构
work_disk
├─.src
│  └─test.pc
├─.include2
│  ├─mymacrodef.h
│  └─procafter.h
/*test.pc*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"mymacrodef.h"
#ifndef  ORA_PROC
#include"procafter.h"
#endif

int_ty foo(int_ty a)
{
EXEC SQL BEGIN DECLARE SECTION;
  int_ty  aary[QUEUE_SIZE][20];  -- Declare host  variable.
EXEC SQL END DECLARE SECTION;
printfmylog("foo","indexs:%d",sizeof(array)/sizeof(int_ty));
}
/*mymacrodef.h*/
#ifndef MYMACRODEF__H_
#define MYMACRODEF__H_
typedef int int_ty;
#define QUEUE_SIZE 44
#endif
/*procafter.h*/
#ifndef PROCAFTER__H_
#define PROCAFTER__H_
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<pthread.h>
#include<time.h>
#include"mymacrodef.h"
#define printmylog(str,f,...)  printf("%s" f,str,##__VA_ARGS__);
#endif

#makefile test part
CC=gcc
PROC=proc
CCINCLUDE= -I./  -I../include2/
LINKLIBS= -L$(ORACLE_HOME)/lib/ -lclntsh
PROCOPTION= parse=full include={./,../include2/} lines=yes 
test.o:test.pc
	$(PROC) $(PROCOPTION) iname=test.pc
	$(CC)  $(CCINCLUDE) -c  test.c

PS:我的改动后又遇到undefined reference 这个是我makefile中的

LINKLIBS+= -L$(ORACLE_HOME)/lib/  -lclntsh  
#写错成$(LINKLIBS)开头了
相关原文资源截取
ORA_PROC Macro

ora_proc :https://docs.oracle.com/database/121/LNPCC/pc_05adv.htm#LNPCC3289

Pro*C/C++ predefines a C preprocessor macro called ORA_PROC that you can use to avoid having the precompiler process unnecessary or irrelevant sections of code. Some applications include large header files, which provide information that is unnecessary when precompiling. By conditionally excluding such header files based on the ORA_PROC macro, the precompiler never reads the file.

The following example uses the ORA_PROC macro to exclude the irrelevant.h file:

#ifndef  ORA_PROC
#include <irrelevant.h>
#endif

Because ORA_PROC is defined during precompilation, the irrelevant.h file is never included.

The ORA_PROC macro is available only for C preprocessor directives, such as #ifdef or #ifndef. The EXEC ORACLE conditional statements do not share the same namespaces as the C preprocessor macros. Therefore, the condition in the following example does not use the predefined ORA_PROC macro:

EXEC ORACLE IFNDEF ORA_PROC;
   <section of code to be ignored>
EXEC ORACLE ENDIF;

ORA_PROC, in this case, must be set using either the DEFINE option or an EXEC ORACLE DEFINE statement for this conditional code fragment to work properly.

Directives Ignored被忽略的宏定义指令

Some C preprocessor directives are not used by the Pro*C/C++ preprocessor. Most of these directives are not relevant for the precompiler. For example, #pragma is a directive for the C compiler—the precompiler does not process it. The C preprocessor directives not processed by the precompiler are:
#, to convert a preprocessor macro parameter to a string constant

##, to merge two preprocessor tokens in a macro definition

#error, to produce a compile-time error message

#pragma, to pass implementation-dependent information to the C compiler

#line, to supply a line number for C compiler messages

Preprocessor Directives 预编译器proc指令

The preprocessor directives that Pro*C/C++ supports are:

#define, to create macros for use by the precompiler and the C or C++ compiler

#include, to read other source files for use by the precompiler

#if, to precompile and compile source text based on evaluation of a constant expression to 0

#ifdef, to precompile and compile source text conditionally, depending on the existence of a defined constant

#ifndef, to exclude source text conditionally

#endif, to end an #if or #ifdef or #ifndef command

#else, to select an alternative body of source text to be precompiled and compiled, in case an #if or #ifdef or #ifndef condition is not satisfied

#elif, to select an alternative body of source text to be precompiled and compiled, depending on the value of a constant or a macro argument


错误列表可以去Oracle的错误集查找 或者下面一篇博文
《Pro*C 错误的详细信息以及解决方法(收下备用)》https://blog.csdn.net/luolunz/article/details/9211259?utm_source=app

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值