Linux 环境下调用C++库ocilib操作Oracle数据 -详细介绍

1. 配置oracle环境和安装ocilib库

这里主要参考的是这篇文章,Linux 环境下调用C++库ocilib操作Oracle数据
期间遇到各种各样问题,现记录如下


1. oracle环境配置中碰到的问题

  1. Instant Client Downloads for Linux x86-64 (64-bit)

  2. Linux下软件安装详解(rpm包、deb包、zip包等)

  3. 在这里插入图片描述,打开服务器浏览器联网

  4. Ubuntu系统中安装RPM格式包的方法

  5. 配置 oracle环境变量:

    • sudo vi /etc/profile 在profile 添加 下面三行
      在这里插入图片描述

    • source /etc/path 更新配置(最好重启下)

    • 命令行输入:sqlplus,测试是否成功,正常如下:
      在这里插入图片描述

    • sqlplus: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory:解决办法
      在这里插入图片描述

    • sqlplus 测试是否能成功连接数据库 sqlplus 用户名/密码@ip地址:端口/service_name


2. 安装ocilib碰到的问题

在这里插入图片描述
6. 解决错误line 81: aclocal-1.14: command not found
7. ac_headers_path=/usr/include/oracle/11.2/client64
8. maake install 时
在这里插入图片描述

2. 调用ocilib库,生成c++客户端

ocilib库默认位置:/usr/local/lib
oclib.h头文件位置:安装时用的压缩包的目录下的include下
oracle库默认位置:/usr/lib/oracle/11.2/client64/lib

  1. 相关目录解释
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述

  1. . test.cpp
#include "ocilib.h"
void err_handler(OCI_Error *err)
{
    printf("%s\n", OCI_ErrorGetString(err));
}
int main(void)
{
    OCI_Connection* cn;
    
 
    if (!OCI_Initialize(err_handler, NULL, OCI_ENV_DEFAULT))
    {
        return EXIT_FAILURE;
    }

 
    cn = OCI_ConnectionCreate("(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=IP)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=ORCL1)))", "usr", "pwd",OCI_SESSION_DEFAULT);
    printf("Server major    version : %i\n", OCI_GetServerMajorVersion(cn));
    printf("Server minor    version : %i\n", OCI_GetServerMinorVersion(cn));
    printf("Server revision version : %i\n\n", OCI_GetServerRevisionVersion(cn));
    printf("Connection      version : %i\n\n", OCI_GetVersionConnection(cn));
    OCI_ConnectionFree(cn);
    OCI_Cleanup();
 
    return EXIT_SUCCESS;
}

  1. makefile文件
    需要修改的地方:

TARGET 我的项目名就是test,所以就是TARGET = test.$(SUFFIX))

#############################################################   
# Makefile for execute program.  
# 编译运行程序文件  
#############################################################  

include ./global.make

#SYSINC = -I../ 

#set your own environment option  
CPPFLAGS= $(BASICOPTS) $(INCLUDE)
CFLAGS= $(CPPFLAGS)
LDFLAGS=
DEPFLAGS= -MM $(BASICOPTS) $(INCLUDE)

#set your inc and lib
INCLUDE = -I../ $(SYSINC)
LIB = $(SYSLIBS) 

#make target lib and relevant obj   
TARGET = test.$(SUFFIX)

SRCS = $(wildcard *.cpp)

OBJS = $(patsubst %cpp,%o,$(SRCS))

DEPENDS=$(SRCS:%.cpp=%.d)
TASKPATH= $(PROGTASKPATH)
  
.PHONY: all clean init alld cleand
#all target  
all: init clean $(TARGET)
	cp -prf $(TARGET)  $(TASKPATH)

init:
	mkdir -p $(TASKPATH)

$(TARGET):$(OBJS)
	$(CC) $(LDFLAGS) -o $@ $^ $(LIB) $(RUNLIB) 

alld: init $(TARGET) cleand
	cp -prf $(TARGET)  $(TASKPATH)

%.d:%.cpp
	-@set -e; rm -f $@; \
	$(CC) $(DEPFLAGS) $< > $@.$$$$; \
	sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
	rm -f $@.$$$$

ifeq ($(MAKECMDGOALS),alld)
-include $(DEPENDS)
endif

cleand:
	-@rm -f $(DEPENDS)

clean:
	rm -f $(OBJS) $(TARGET)
	-@rm -f $(DEPENDS)




  1. globa.make 文件
    需要修改的地方:

SYSINC:引用的ocilib.h头文件的位置
DB_BASIC_LIBS :oracle库、ocilib库的位置

UNAME=$(shell uname -s)

ifeq ($(UNAME), SunOS)
SUB_UNAME=$(shell uname -p)
ifeq ($(SUB_UNAME), sparc)
OS=OS_SOLARIS_SPARC
SUFFIX=dxe
else
OS=OS_SOLARIS_X86
SUFFIX=xxe
endif
CC = cc
BASICOPTS =-g -D_H9000V6  
SPECIALLIBS =  -lsocket
endif

ifeq ($(UNAME), AIX)
OS=OS_AIX
SUFFIX=axe
CC=gcc
BASICOPTS =-g -Wall -D_LINUX_SOURCE_COMPAT -D_H9000V6 
SPECIALLIBS =  
endif

ifeq ($(UNAME), Linux)
OS=OS_LINUX
SUFFIX=lxe
CC=g++
BASICOPTS =-g -Wall -Dlinux -D_LINUX_SOURCE_COMPAT -DSTRESS_TEST -gdwarf-2 -std=c++11 -Wno-deprecated -D_GLIBCXX_USE_CXX11_ABI=1
SPECIALLIBS = 
endif


ifndef OS
	$(error makefile has not supported the current os.)
endif

LIBTASKPATH= /home/hust/lib

PROGTASKPATH= /home/hust/bin

SYSINC = -I../ -I/home/hust/jars/flowd/ocilib-4.6.0/include

COMPILE = $(CC)

DB_BASIC_LIBS = -L/usr/lib/oracle/11.2/client64/lib -lclntsh -L/usr/lib/oracle/11.2/client64/lib -locci -L/usr/local/lib -locilib

SYSLIBS = $(DB_BASIC_LIBS)
		


3. 运行c程序,连接数据库

  1. 在上面的基础上,cd到 /home/hust/jars/flowd/test 下,先执行make命令生成可执行文件
    在这里插入图片描述
  2. 执行 ./test.lxe
    在这里插入图片描述

参考内容:
1 . Linux 环境下调用C++库ocilib操作Oracle数据
2. ocilib 官方文档:ocilib 官方文档

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Utgard 是一个Java,用于连接 OPC DA 服务器,如果你想在Linux环境下使用C++调用Utgard访问OPC DA服务器,你需要使用Java Native Interface(JNI)。 以下是一些步骤: 1.首先,在Linux系统上安装Java Development Kit(JDK)。 2.然后创建一个Java类来连接OPC DA服务器并实现所需的功能。 3.编译Java类并生成一个Java动态链接(.so文件)。 4.在C++代码中使用JNI调用Java动态链接。 下面是一个简单的示例: Java类: ```java import org.jinterop.dcom.common.JIException; import org.jinterop.dcom.core.JIVariant; import org.jinterop.dcom.core.JIString; import org.openscada.opc.lib.common.ConnectionInformation; import org.openscada.opc.lib.da.Item; import org.openscada.opc.lib.da.ItemState; import org.openscada.opc.lib.da.Server; import org.openscada.opc.lib.da.SyncAccess; public class OPCClient { public static void main(String[] args) throws Exception { // connect to an OPC DA server ConnectionInformation ci = new ConnectionInformation(); ci.setHost("localhost"); ci.setUser("user"); ci.setPassword("password"); ci.setClsid("B3AF0BF6-4C0C-4804-A122-6F3B160F4397"); Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor()); // create an item and read its value Item item = server.getItemManager().getItem("Random.Int1"); SyncAccess syncAccess = new SyncAccess(server, 1000); syncAccess.addItem(item); syncAccess.bind(); ItemState itemState = item.read(syncAccess.getTransactionId()).get(); JIVariant jiVariant = itemState.getValue(); int value = jiVariant.getObjectAsInt(); System.out.println(value); // write a value to the item item.write(new JIVariant(new JIString("new value"))); // disconnect from the server server.dispose(); } } ``` 编译Java类并生成一个Java动态链接: ```bash javac -cp .:utgard.jar OPCClient.java javah -classpath .:utgard.jar -jni OPCClient gcc -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -o libOPCClient.so OPCClient.c -L. -lutgard ``` C++代码: ```c++ #include <jni.h> int main() { JavaVM *jvm; JNIEnv *env; JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_8; vm_args.nOptions = 0; vm_args.ignoreUnrecognized = JNI_FALSE; JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args); jclass cls = env->FindClass("OPCClient"); jmethodID mid = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V"); jobjectArray args = env->NewObjectArray(0, env->FindClass("java/lang/String"), NULL); env->CallStaticVoidMethod(cls, mid, args); jvm->DestroyJavaVM(); } ``` 在编译C++代码时需要链接utgard和jni,如下所示: ```bash g++ -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -L. -lutgard -ljvm -o main main.cpp ``` 注意:以上示例仅演示了如何使用JNI调用Java动态链接,具体的OPC DA连接实现需要根据自己的需求进行编写。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值