2010-06-07 12 views
20

Dizin yapısı nedeniyle, C çalıştırılabilir içine bağlanan B paylaşılan kitaplığına bağlı bir statik kitaplık A olarak ayarlanmış bir C++ projem var. (Windows üzerinde biz A.lib, B.dll olsun böylece bu, CMake kullanarak çapraz platform projedir ve C.exe ve Linux üzerinde aldığımız libA.a, libB.so ve C.) Kütüphane A (A/initA.cpp tanımlanan A_init) init işlevi vardır, Bu, C ana adlı kitaptan çağrılan B init işlevinden (, B/initB.cpp olarak tanımlanmıştır) çağrılmaktadır. Böylece, B, A_init (ve initA.cpp'da tanımlanan tüm semboller) bağlanırken B'a (istediğiniz davranışımıza) bağlanır.Bir nesne dosyasının bir çalıştırılabilir dosyaya bağlanırken statik kitaplığa dahil edilmesine nasıl zorlanır?

sorun A kütüphanesi de dinamik olarak yüklenmiş tarafından tasarlanmıştır (A/Afort.f tanımlanan Af) bir fonksiyon (Windows LoadLibrary/GetProcAddress ve Linux dlopen/dlsym yani) tanımlar gelir. B kitaplığından Af referansı olmadığından, A/Afort.o sembolleri B'a dahil değildir. Windows'ta, biz yapay olarak pragma kullanarak bir başvuru oluşturabilirsiniz:

#pragma comment (linker, "/export:_Af") 

bu pragma olduğundan, sadece (Visual Studio 2008 kullanılarak) Windows üzerinde çalışır. Linux üzerinde çalışan almak için, biz A/initA.cpp aşağıdaki ekleyerek denedim: Bu sembol AfB nihai bağlantı dahil edilecek yol açmaz

extern void Af(void); 
static void (*Af_fp)(void) = &Af; 

. Af sembolünün B'a bağlanması için nasıl zorlayabiliriz? Eğer B oluştururken

cevap

12

Bu benim orijinal girişimi çoğunlukla orada çıkıyor. Aşağıdaki çalışır: kendi kendine yeten önişlemci makro bu enkapsüle isteyenler için

extern "C" void Af(void); 
void (*Af_fp)(void) = &Af; 

:

#if defined(_WIN32) 
# if defined(_WIN64) 
# define FORCE_UNDEFINED_SYMBOL(x) __pragma(comment (linker, "/export:" #x)) 
# else 
# define FORCE_UNDEFINED_SYMBOL(x) __pragma(comment (linker, "/export:_" #x)) 
# endif 
#else 
# define FORCE_UNDEFINED_SYMBOL(x) extern "C" void x(void); void (*__ ## x ## _fp)(void)=&x; 
#endif 

thusly hangisi kullanılır:

FORCE_UNDEFINED_SYMBOL(Af) 
3

Sen --undefined seçeneğini kullanabilirsiniz:

g++ -Wl,--undefined,Af -o libB.so ... 
0

onlar (umarım) bağlantı zaman libB.so kütüphanede zorla konum böylece B/initB.cpp içine bu satırları koyarak deneyin.

Ama neden bu şekilde yapmak zorundasınız? Bağdaştırıcının doğru şeyi otomatik olarak yapmasına neden olan, çalıştırılabilir çalıştırılabilir referanslar (ya da onun arayıcısı) bu şekilde ayarlanamaz mı?

+0

C aslında bir betik dili ön harfidir, B dil motorudur ve A, motorun kullanacağı bir dizi yerel kod yöntemidir. İyi tanımlanmış bir yabancı fonksiyon arayüzüne sahip önceden var olan bir dili uyguluyoruz. A ve B ayrı ekipler tarafından üretilir; A-ekibinin A dizininde yazdığı her şeyi tutmayı tercih ederiz. –

0

Eğer gcc'nin C++ 0x özellikleri kullanabilirsiniz ise (-std = C++ 0x), sonra hile yapabilirsinizfonksiyon varsayılan şablon argümanları. Geçerli C++ standardından itibaren, işlev şablonları için varsayılan argümanlara izin verilmez. Bu c etkinken ++ 0x, gibi bir şey yapabilirsiniz: - ... Statik kütüphanenin bazı başlık dosyasında

template< class T = int > 
void Af() 
{ 
} 

Sonra karşılık gelen cpp dosyası kullanımı açık şablon örneği başlatıldığında içinde ...

template void Af(); 

Bu henüz/adlandırılan kaynak gösterilmemiş olsa fonksiyonu Af sembollerini üretecektir. Bu, varsayılan şablon argümanı nedeniyle bir tür belirtmeniz gerekmediği için arayanları etkilemez. Sadece işlev bildiriminden önce template <class T = int >'u ekleyin ve uygulama dosyasında açık bir şekilde örnekleyin.

HTH,

+1

Ne yazık ki, bu işe yaramaz çünkü Af aslında bir Fortran prosedürüdür. –

+0

Öyleyse, Af <(...) 'i çağıran bir' C 'sarıcı yapın;' C 'i.e. alt harf tarafından eklenen işlev adından fortran işlevlerini çağırabilirsiniz; argümanlar için google nitty cesur ayrıntıları, ben donno C++ çağıran ben donno]. C++ 'dan bu' C 'sarıcıyı arayın. BTW, çalıştığım önde gelen finans şirketlerinden biri, antika/berbat kodunu :-) yönetmiştir :-) – Abhay

+0

Bu, 2 yıl sonra bir çaylak koruyucusu tarafından büyük olasılıkla kaldırılacak olan çok açık bir koddur. En azından makro anlamak için yeterince açık. – xryl669

5

MSVC#pragma comment(linker, "/include:__mySymbol")

gcc-u symbol

2

FORCE_UNDEFINED_SYMBOL makrosunu yazmak için daha iyi bir yol var. Sadece bu fonksiyon göstergesini bir boşluğa * aktarın. Daha sonra herhangi bir işlevle veya bu konuyla ilgili verilerle çalışır. Ayrıca, makronuzun gcc kısmı MSVC için de çalışırken MSVC pragmas ile neden uğraşırsınız. Yani benim basitleştirilmiş versiyonu olacaktır:

FORCE_UNDEFINED_SYMBOL(Af) 

Ama elimden onun sembollerini yaşıyor kütüphane içerir programda kullanılması gerekir:

#define FORCE_UNDEFINED_SYMBOL(x) void* __ ## x ## _fp =(void*)&x; 

thusly hangisi kullanılır.

İlgili konular