跳到主要內容

發表文章

目前顯示的是 2017的文章

Windows 編譯 OpenSSL 1.1.0

Windows 編譯 OpenSSL 1.1.0 OpenSSL 的編譯方式在原始碼中的文件 NOTES.WIM 提到詳細的介紹在 INSTALL 文件中。 需要使用 Visual Studio IDE OpenSSL 原始碼 ActivePerl 或其他 Perl 執行環境 本文使用 Windows 10 版本1703 組建 15063.413 Visual Studio 2017 Community OpenSSL 1.1.0f ActivePerl 5.24.1.2402-MSWin32-x64-401627 32位元與64位元要分開編譯,release與debug也要分開 因為 openssl 的 Makefile 沒有自動處理四種版本,若不各自編譯會出錯, 複製四分 openssl 原始碼,分為 32 位元與 64 位元及 release 與 debug,例: c:\openssl-x86 、 c:\openssl-x86-dbg 、 c:\openssl-x64 、 c:\openssl-x64-dbg x86 以系統管理員權限執行 x86 Native Tools Command Prompt for VS 2017 ,通常安裝 Visual Studio IDE 時會新增捷徑到開始列表 ,而 2017 Community 版本的檔案位置為 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat ,不能直接執行 vcvars32.bat , 應該以命令提示字元(cmd.exe)執行 cd 到解壓縮的openssl資料夾內,例: cd c:\openssl-x86 執行以下 perl Configure VC-WIN32 no-asm --prefix=C:\openssl-msvc2017-x86 mkdir C:\openssl-msvc2017-x86 nmake nmake test nmake install 這樣會輸出在 C:\openssl-msvc2017-x86 x86-debug 以系統管理員權限執行 x86 Nati

Dynamically loaded libraries 動態載入庫 #3 C++ 類別載入

Dynamically loaded libraries 動態載入庫 #3 C++ 類別載入 繼上一篇 Dynamically loaded libraries 動態載入庫 #2 C++ 提到 libdl 是 C 函式庫,不包含類別的功能, 而 C++ 物件導向的特性之一 多形 可以用來達成動態載入類別的功能, 這樣唯一不足的點是, 在要使用動態類別庫的專案中需要加入類別介面標頭, 而不能在讓編譯器完全不知道類別介面的狀況下動態載入。 範例類別庫 以下程式為了節省版面沒有使用 #include 防範 HelloWorld.hpp (介面) class HelloWorld { public: HelloWorld() {} virtual ~HelloWorld() {} virtual void hello() {} }; extern "C"{ HelloWorld* create_object(); void destroy_object(HelloWorld* object); } 會直接實作 HelloWorld 的方法是為了使用上的方便, 不論是不實作或是讓它=0都會有些相對應的問題, 因此我還是將這個 HelloWorld 稱為介面。 create_object 和 destroy_object 兩個函式用於轉發建構子與解構子, 這下就有辦法呼叫其他類別庫中的 HelloWorld 子類別建構子、解構子, 也剛好有 HelloWorld 介面,如此就可以動態載入類別了。 MyHelloWorld.hpp (要被動態載入的類別) #include "HelloWorld.hpp" class MyHelloWorld: public HelloWorld { public: MyHelloWorld(); virtual ~MyHelloWorld(); virtual void hello(); }; MyHelloWorld.cpp #include "MyHelloWorld.hpp" #include <iostream> /* 轉發建構子*/ HelloWor

Dynamically loaded libraries 動態載入庫 #2 C++

Dynamically loaded libraries 動態載入庫 #2 C++ 繼上一篇 Dynamically loaded libraries 動態載入庫 這篇寫如何寫C++的動態載入庫,因為C++編譯器會修飾函式名稱,所以不能直接用C的方式寫庫 範例函式庫 mylib.h extern "C" { void hello(); void world(); } 與C的不同處是這裡要加上 extern "C" {} 包住不希望被編譯器修飾的函式 hello.cpp #include "mylib.h" #include <iostream> void hello(){ std::cout << "Hello" ; } world.cpp #include "mylib.h" #include <iostream> void world(){ std::cout << "World" ; } 編譯 $ g++ -c -fPIC hello.cpp world.cpp $ g++ -shared -o libmylib.so hello.o world.o 編譯的方式除了從gcc改為g++之外,沒有其他改變 使用方式 main.cpp int main() { void* handle = dlopen("./libmylib.so", RTLD_LAZY); void (*f1)() = (void (*)()) dlsym(handle, "hello"); void (*f2)() = (void (*)()) dlsym(handle, "world"); f1(); f2(); dlclose(handle); return 0; } 使用方式和C一模一樣,這裡假設不會出錯誤 編譯 編譯時要一樣連結 libdl,使用 -ldl $ g++ main.cpp -ldl

Dynamically loaded libraries 動態載入函式庫

Dynamically loaded libraries 動態載入庫 動態載入函式庫可以由程式控制在需要時才載入、釋放,在編譯連結時不需要相關的界面與函式庫,可以用來設計軟體插件之類的功能。 範例函式庫 mylib.h void hello(); void world(); hello.c #include "mylib.h" #include <stdio.h> void hello(){ printf("Hello"); } world.c #include "mylib.h" #include <stdio.h> void world(){ printf("World"); } 編譯 $ gcc -c -fPIC hello.c world.c $ gcc -shared -o libmylib.so hello.o world.o -fPIC 要編譯器產生 position-independent code -shared 編譯 Shared Library -o libmylib.so 函式庫檔案名稱為 libmylib.so 這裡沒使用 soname 等便於版本維護的參數 這樣會建立一個 libmylib.so 共享函式庫 使用方式 main.c #include <dlfcn.h> /* 動態載入要用的相關函式標頭 */ #include <stdio.h> int main() { /* 載入函式庫 libmylib.so */ void* handle = dlopen("./libmylib.so", RTLD_LAZY); /* 若有錯誤可以取得錯誤訊息 */ char* err = dlerror(); if (err) { printf(err); return 0; } /* 取得void hello()函式的指標 */ void (*f1)() = (void (*)()) dlsym(handle