Невозможно связать предварительно скомпилированный файл

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

Я написал этот пример программы 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

Команда работает, и я могу использовать встроенный компилятор 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 в коде.

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


person Ahmad    schedule 10.05.2018    source источник
comment
Где-то, вероятно, в общедоступном изображении, находится код, реализующий вызовы базы данных. Поскольку в вашем примере ничего не делалось, не было фактической ссылки на тот код, который нужно было разрешить, компоновщик весело пошел своим путем без жалоб. Ссылка на общедоступное изображение обычно делается с помощью файла параметров. Ссылка. (Возможно, LIBCLNTSH.EXE где-то прячется.)   -  person HABO    schedule 10.05.2018
comment
@HABO, не могли бы вы уточнить, что мне делать, чтобы решить эту проблему? Должен ли я найти указанный файл? Тогда что?   -  person Ahmad    schedule 10.05.2018
comment
Содержит ли документация Oracle™ раздел о создании приложений? Включены ли примеры программ в установку Oracle™?   -  person HABO    schedule 10.05.2018
comment
@HABO, не могли бы вы указать мне веб-сайт / учебник, который выполняет эти шаги? Как узнать, содержит ли установка Oracle образцы файлов? Я нашел детали для Windows и Linux, но не для OPENVMS   -  person Ahmad    schedule 10.05.2018
comment
До сих пор я избегал использования Oracle™. Документация по связыванию находится здесь. Информация о примерах приведена здесь. Это превышает мои познания в предмете.   -  person HABO    schedule 10.05.2018


Ответы (3)


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

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

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

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

в

 CX3$Z6SQLCXTPPVPJP6SQLXD384K7FP

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

person user3344003    schedule 11.05.2018
comment
Что бы ни делал CODE=CPP, он выглядит как параметр для прекомпилятора. Исходный код выглядит как C, но компилируется компилятором C++. Неудивительно, имена искажены. Если он знает нужные библиотеки или общедоступные изображения, искажение имени не будет проблемой. Ни на Альфе, ни на I64, которая здесь платформа. Как можно видеть, компоновщик VMS красиво искажает искаженное имя. Использование предоставленных Oracle командных процедур, скорее всего, гарантирует использование правильных библиотек. Чтобы ответить на первоначальный вопрос: вы смешиваете C и C++ и не используете предоставленные командные процедуры. - person user2116290; 12.05.2018

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

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

person qustogusto    schedule 30.03.2019

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

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

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

Удачи.

person Bob Jarvis - Reinstate Monica    schedule 11.05.2018