第八天
因为Oracle下的函数定义卡住了,所以想试试OCI能不能实现。从ORAL_HOME\ora92\D:\oracle\ora92\oci\samples\下看到了readpipe.c,使用OCI方法轮询Oracle的一个命名管道,于是想试试,可是又被卡在了命名管道的创建上面,Oracle下的开发我实在是不行啊。。。没办法了,我决定要走Oracle调用.dll这条路,因为如果能走通这就是一条新路,以后再有处理Oracle数据的地方我就不用在Oracle中费劲了,而且还可以像Windows一样提供服务给Oracle使用,多爽啊,拼了~~在网上查啊查,又把昨天编译成功的函数拿出来比对,终于把函数创建出来了,眼泪哗哗的啊。然后重新写了一个不依赖与Windows和MFC的标准动态库,在Oracle中注册后开始尝试调用.dll(库文件注册后想替换只需要覆盖.dll即可),
出现如下错误:
ORA-06521:PL/SQL: 映射函数时出错
ORA-06522:Unable to load symbol from DLL
崩溃。。
这个错误在例子中提到了,说编译动态库的时候命令行参数没有/EXPORTUT调用的时候就会报出这个错误,可是我加入这个参数后每次连接的时候都说它是无效参数然后就被忽略了,晕。。不知道为什么只能去网上找,找到了很多编译参数的说明文档可是都没有/EXPORTUT这个参数,无意中看到了我用的例子的原帖,发现原帖中/EXPORT和UT之间有一个笑脸的符号,想到这个符号会不会是中间的字符被转义了,于是开始查/EXPORT的定义规则,发现都是/EXPORT:XXX这样定义的。在联系上dll工程中的代码,恍然大悟,原来应该是/EXPORT:OUT,定义了输出的函数名字。改掉之后果然上面的错误就没有了。不过又有了新问题:
ORA-28576:丢失与外部代理程序的 RPC 连接。
莫名其妙,重启了sql-plus也不管用,只能再去网上找答案。摘录原因如下:
Oracle调用外部程序有两种方式一种是标准的C调用,一种是Pascal调用。缺省是标准的C调用.不支持stdcall。Pascal调用方式在VC里已经不支持了。所以如果你的程序是用VC开发的,唯一的办法就是修改你的动态链接库源代码,改为标准的C调用,重新编译
Example:
TESTPROC_API int fnTestProc(void); ==>
extern "C"
{
TESTPROC_API int fnTestProc(void);
}
如果你就想调用没有源代码的动态链接库怎么办,因为大部分Windows下的动态链接库都是定义成stdcall方式的,所以
你只能自己创建一个动态链接库工程,然后封装没有源代码的动态链接库函数。
按照上面的说法把我的动态库中的__stdcall去掉,重新编译后替换原有的Oracle库,使用select语句调用,结果出来了,哈哈哈哈哈哈~~~~欣喜若狂啊
不过目前还只是使用数字型的参数和返回值,字符串类型(varchar2)的还没有尝试,网上有先驱者说他用int类型的成功后,使用varchar2类型调用就失败了,看来还需要努力啊,实在不行就使用临时表的方法来解决,我还能省点事呢,呵呵。。。
下面是Oracle调用.dll的全过程和涉及到的.dll源码,Oracle中的函数定义以及全部的操作过程:
首先oracle环境配置: