كيف استدعاء وظيفة مكتبة محملة رمز في التطبيق الرئيسي؟

StackOverflow https://stackoverflow.com/questions/392416

  •  23-08-2019
  •  | 
  •  

سؤال

عند تحميل مكتبة مشتركة مفتوحة عبر الوظيفة dlopen(), ، هل هناك طريقة لتدوين الوظائف في البرنامج الرئيسي؟

هل كانت مفيدة؟

المحلول

رمز 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 MANPAGE، وتعديله):

#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 في Windows، كما أنه سيجعل أيضا اتصالا نظيفا بين المكتبة والبرنامج الرئيسي (لديك سيطرة دقيقة على ما يمكن استدعاؤه وليس)، ولكنه يتطلب أيضا المزيد من حفظ المنزل.

نصائح أخرى

نعم، إذا قمت بتوفير مكتبتك مؤشرا لهذه الوظيفة، فأنا متأكد من أن المكتبة ستتمكن من تشغيل / تنفيذ الوظيفة في البرنامج الرئيسي.

هنا مثال على ذلك، لم تجميعها حذارا؛)

/* 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);
}

ال dlopen() وظيفة، كما تمت مناقشتها بواسطة Litb، يتم توفيرها في المقام الأول على الأنظمة باستخدام ملفات كائنات تنسيق ELF. إنه قوي نوعا ما وسوف يتيح لك السيطرة على ما إذا كان الرموز المشار إليه بواسطة المكتبة المحملة يمكن أن يكون راضيا عن البرنامج الرئيسي، ودعهما راضيا بشكل عام. لا تكون جميع أنظمة تحميل المكتبة المشتركة مرنة - كن على علم إذا كانت تأتي لتنفيذ التعليمات البرمجية الخاصة بك.

تعمل آلية رد الاتصال التي حددتهاhhaafez الآن أن الخلل في هذا الرمز يتم تقويمه خارجا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top