Как загруженная библиотечная функция назвала бы символ в главном приложении?

Сделайте скалярную функцию для использования каждый раз

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
CREATE FUNCTION FormatBracket(@Value as money)
RETURNS varchar(30)
AS
BEGIN
    DECLARE @RETVAL AS varchar(30);
    select
         @retval = case when @VALUE < 0 THEN 
                                    '(' + cast(ABS(@value) as varchar(28)) + ')'
                      else
                                    cast(@value as varchar(28))
                    END;

    RETURN @RETVAL;     

END
GO

, затем

SELECT num, dbo.FormatBracket(num)
AS frmtd
FROM (
SELECT    0 AS num UNION ALL
SELECT  945        UNION ALL
SELECT -945
) tests

Я использовал тип переменной MONEY, который может быть любым числовым типом, я не деньги наверняка были в 2005 году

9
задан Jonathan Leffler 25 December 2008 в 06:11
поделиться

3 ответа

Код dlo.c (lib):

#include <stdio.h>

// function is defined in main program
void callb(void);

void test(void) {
    printf("here, in lib\n");
    callb();
}

Скомпилируйте с

gcc -shared -olibdlo.so dlo.c

Здесь код основной программы (скопированный с dlopen страницы справочника и скорректированный):

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

void callb(void) {
    printf("here, i'm back\n");
}

int
main(int argc, char **argv)
{
    void *handle;
    void (*test)(void);
    char *error;

    handle = dlopen("libdlo.so", RTLD_LAZY);
    if (!handle) {
        fprintf(stderr, "%s\n", dlerror());
        exit(EXIT_FAILURE);
    }

    dlerror();    /* Clear any existing error */

    *(void **) (&test) = dlsym(handle, "test");

    if ((error = dlerror()) != NULL)  {
        fprintf(stderr, "%s\n", error);
        exit(EXIT_FAILURE);
    }

    (*test)();
    dlclose(handle);
    exit(EXIT_SUCCESS);
}

Сборка с

gcc -ldl -rdynamic main.c

Вывод:

[js@HOST2 dlopen]$ LD_LIBRARY_PATH=. ./a.out
here, in lib
here, i'm back
[js@HOST2 dlopen]$

-rdynamic опция помещает все символы в динамическую таблицу символов (который отображается в память), не только названия используемых символов. Читайте далее об этом здесь. Конечно, можно также обеспечить указатели функции (или структура указателей функции), которые определяют интерфейс между библиотекой и основной программой. Это - на самом деле метод, что я выбрал бы, вероятно. Я получил известие от других людей, которых не настолько легко сделать -rdynamic в окнах, и это также сделало бы для более чистой коммуникации между библиотекой и основной программой (у Вас есть точное управление на том, что можно назвать и не), но также требуется больше обслуживания.

21
ответ дан 4 December 2019 в 08:17
поделиться

Да, Если Вы предоставляете Вашей библиотеке указатель на ту функцию, я уверен, что библиотека сможет выполнить/выполнить функцию в основной программе.

Вот пример, не скомпилировали его, так остерегайтесь ;)

/* in main app */

/* define your function */

int do_it( char arg1, char arg2);

int do_it( char arg1, char arg2){
  /* do it! */
  return 1;
}

/* some where else in main app (init maybe?) provide the pointer */
 LIB_set_do_it(&do_it);
/** END MAIN CODE ***/

/* in LIBRARY */

int (*LIB_do_it_ptr)(char, char) = NULL;

void LIB_set_do_it( int (*do_it_ptr)(char, char) ){
    LIB_do_it_ptr = do_it_ptr;
}

int LIB_do_it(){
  char arg1, arg2;

  /* do something to the args 
  ...
  ... */

  return LIB_do_it_ptr( arg1, arg2);
}
4
ответ дан 4 December 2019 в 08:17
поделиться

dlopen() функция, как обсуждено @litb, прежде всего, обеспечивается в системах с помощью файлов объекта формата ELF. Это довольно мощно и позволит Вам управлять, могут ли символы, на которые ссылается загруженная библиотека, быть удовлетворены из основной программы и обычно позволяют им быть удовлетворенными. Не все общие загрузочные системы библиотеки так же гибки - знать, если это приходит к портированию Вашего кода.

Механизм обратного вызова, обрисованный в общих чертах @hhafez, работает теперь, когда петли в том коде разглажены.

1
ответ дан 4 December 2019 в 08:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: