Невозможно связать предварительно скомпилированный файл - PullRequest
0 голосов
/ 10 мая 2018

Я использую OpenVMS V8.4 в качестве сервера базы данных Oracle 10g со встроенным компилятором CXX, а также компилятором PROC, предоставленным oracle.

Я написал этот пример программы на С:

sample.c

#include<stdio.h>
exec sql include sqlca;  // adds Oracle PLSQL library
                         // same as #include<sqlca.h>

main() {
    printf("Hello, World!\n");
}

тогда я его скомпилировал

DEVSERVER> PROC SAMPLE.C SAMPLE.PC

Команда работает find, и я могу затем использовать встроенный компилятор CXX:

DEVSERVER> CXX SAMPLE.PC

Команда работает без ошибок, и теперь я могу использовать встроенную команду LINK:

DEVSERVER> LINK SAMPLE

теперь я могу запустить файл:

DEVSERVER> RUN SAMPLE

и я получаю ожидаемый результат:

Привет, мир!

Итак, все в порядке. Но моя программа пока не делает ничего полезного. Итак, давайте сначала подключимся к схеме базы данных. Я изменил SAMPLE.C на:

#include<stdio.h>
exec sql include sqlca; 

main() {
    printf("Hello, World!\n");

    exec sql connect scott identified by tiger;
    // I skipped checking for sqlca.error since LINKer wont even allow
    //  me to create EXE of this file
}

Теперь я прекомпилирую, как и раньше:

DEVSERVER> PROC SAMPLE.C SAMPLE2.PC
DEVSERVER> CXX SAMPLE2.PC
DEVSERVER> LINK SAMPLE2

и вот где я получаю эту ошибку:

%ILINK-W-NUDFSYMS, 1 undefined symbol:
%ILINK-I-UDFSYM,  CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP
%ILINK-W-USEUNDEF, undefined symbol CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP refernced
        source code name: "sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *)"
        section: .text
        offset: %X0000000000000350 slot: 2
        module: SAMPLE2
        file: DEV$SERVER[SOURCE]SAMPLE2.OBJ;1

Та же самая ошибка возникает всякий раз, когда я пытаюсь выполнить любой оператор SQL в блоке exec sql в коде.

Что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 11 мая 2018

@ user3344003 ответ возвращает воспоминания.:-) Да, он прав - имя процедуры, созданной для обработки EXEC SQL, искажается, но, поскольку она генерируется (в ассемблере, IIRC) препроцессором SQL, вам придется немного обойти эту проблему.

В прошлом мы использовали для этого отдельный файл .c с кучей процедур, каждая из которых выполняла либо отдельный оператор SQL, либо логическую группу операторов SQL.необходимо для выполнения задачи.У нас также был файл .h с прототипами, которые соответствовали подпрограммам в файле .c.Заголовок будет #include d в файле .cpp, а прототипы функций в заголовке будут иметь соответствующую extern "C" для указания соглашений о вызовах C и без искажения имен.

Еще одна возможность, которую я никогда не пробовално что может сработать, это просто вставить прототип для sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *) в ваш код с предваряющим extern "C".Возможно, стоит попробовать, но я могу поручиться только за метод .c file.

Удачи.

0 голосов
/ 30 марта 2019

Просто используйте компилятор C на вашем сервере OpenVMS, скорее всего, он тоже установлен.Oracle ProC тоже C, так что вы не столкнетесь с большим количеством причудами CXX.Если нет других не упомянутых факторов, требующих использования C ++ ...

Что касается CXX, то в зависимости от используемой версии существовало требование использовать CXXLINK вместо * 1004.* команда для связывания кода C ++.Очевидно, что при смешивании кода на C и C ++ вам нужно позаботиться о extern "C" для функций на C, определенных в вашем коде.

0 голосов
/ 11 мая 2018

Вы столкнулись с цепной реакцией проблем: компиляция (искажение имени в c ++) и компоновка:

https://docs.oracle.com/cd/E11882_01/server.112/e56697/ch6.htm#VMSAR516

Обратите внимание на параметр CODE = CPP.Это упущение, вероятно, ваша первая большая головная боль.Похоже, вы стали жертвой искажения имен в C ++.Вероятно, ваш компилятор переводит

 sqlcxt(void **, unsigned int *, sqlexd *, const sqlcxp *)

в

 CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP

Затем обратите внимание на процедуры команд в документации для связи с библиотеками Oracle.

...