powered by simpleCommunicator - 2.0.36     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Линковка статических библиотек OBJ/LIB к VB-экзешнику
3 сообщений из 3, страница 1 из 1
Линковка статических библиотек OBJ/LIB к VB-экзешнику
    #39765046
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Интересует как использовать статическую линковку в VB.

1. Вариант. Написание кода статических библиотек самостоятельно на C++, компиляция и линковка с VB-exe.

2. Вариант. Конвертация уже существующих DLL в статическую библиотеку и линковка с VB-exe.

Желательно с примерами проектов и архивчиком *.lib для Link.exe )
...
Рейтинг: 0 / 0
Линковка статических библиотек OBJ/LIB к VB-экзешнику
    #39765073
ATM-TURBO 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Eolt,
Слинковать объектный файл с объектными файлами сделанными в VB6 не проблема.
Существует как минимум 2 пути.

Первый легкий, но он добавляет нежелательный экспорт к исполняемому файлу. Для этого просто нужно в опциях линкера (LinkSwitches) указать параметр EXPORT с нужными функциями и соответственно указать библиотеку для компоновки.
Библиотеки написанные на C/C++ требуют инициализацию рантайма поэтому в качестве точки входа (параметр ENTRY) следует указать mainCRTStartup (_DllMainCRTStartup для DLL). Данная функция инициализирует рантайм и передает управление функции main (wmain). Т.к. точка входа в вб программу называется __vbaS то необходимо как то передать туда управление вместо main. Простейший способ - это написание тривиального редиректора на FASM:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
; init_runtime.asm
format MS COFF

section '.text' code readable executable

public _main
extrn ___vbaS

_main:
jmp ___vbaS


Здесь просто происходит прыжок на точку входа VB6 EXE файла. При соблюдении этих условий будет выполнена инициализация сначала рантайма C/C++ затем инициализация рантайма VB.
К примеру, имеем статическую библиотеку со следующим кодом:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#include <iostream>
#include <Windows.h>

using namespace std;

void _stdcall WriteToConsole(BSTR pszString) {
	wcout << pszString;
}

void _stdcall ReadFromConsole(BSTR *pszRet) {
	WCHAR pszBuf[255];
	wcin.getline(pszBuf, 255);
	*pszRet = SysAllocString(pszBuf);
}


Нам нужно прилинковать статически этот код к EXE файлу сделанному в VB6. Нужно создать 2 версии библиотеки DLL и OBJ/LIB, соответственно для отладки в IDE и для скомпилированного варианта. В VB код будет таким:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
Option Explicit

#If INIDE Then

Public Declare Sub WriteToConsole Lib "..\static_lib\testlib\release\testdll" ( _
                   ByVal pszValue As Long)
Public Declare Sub ReadFromConsole Lib "..\static_lib\testlib\release\testdll" ( _
                   ByVal ppszValue As Long)
                   
Public Declare Function AllocConsole Lib "kernel32" () As Long
Public Declare Function FreeConsole Lib "kernel32" () As Long
Public Declare Function SetDllDirectoryW Lib "kernel32" ( _
                        ByVal pszString As Long) As Long

                            
#Else

Public Declare Sub WriteToConsole Lib "SimpleWay.exe" Alias "?WriteToConsole@@YGXPAG@Z" ( _
                   ByVal pszValue As Long)
Public Declare Sub ReadFromConsole Lib "SimpleWay.exe" Alias "?ReadFromConsole@@YGXPAPAG@Z" ( _
                   ByVal ppszValue As Long)
                   
#End If


В этом случае будет происходить вызов функции из DLL при значении константы условной компиляции INIDE = True и вызов функции из себя же при False .
Пример использования:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
Option Explicit

Sub Main()
    
#If INIDE Then
    
    AllocConsole
    SetDllDirectoryW StrPtr(App.Path)
    
#End If
    
    Dim sName   As String
    
    WriteToConsole StrPtr("Hello! What's your name?" & vbNewLine)
    ReadFromConsole VarPtr(sName)
    
    WriteToConsole StrPtr("How are you, " & sName & "?" & vbNewLine)
    
    sName = vbNullString
    ReadFromConsole VarPtr(sName)
    
    
#If INIDE Then
    
    FreeConsole
    
#End If

End Sub


Для того чтобы обеспечить линковку просто указываем параметры линкеру:
Код: sql
1.
2.
[VBCompiler]
LinkSwitches=OleAut32.lib ..\init_runtime.obj ..\static_lib\testlib\Release\testlib.lib -SUBSYSTEM:CONSOLE -EXPORT:?ReadFromConsole@@YGXPAPAG@Z -EXPORT:?WriteToConsole@@YGXPAG@Z -ENTRY:mainCRTStartup


Данные опции задают консольную подсистему, задают точку входа и экспортируемые функции. Здесь есть одна проблема с родным линкером - в нем есть баг при использовании опции OPT:REF - он отбрасывает импорт от основного EXEшника, поэтому если используется родной линкер то необходимо указать OPT:NOREF также. При использовании нового линкера данные действия необязательны. После компиляции получаем нужный результат:


____________________________________________________________________________________________

Другой способ более сложен, но избавляет от нежелательного экспорта. Данный способ использует замену модуля во время линковки. Для этого необходимо писать специальный Add-in либо использовать мой TrickAdvancedTools (с открытыми исходниками, но нем есть баги которые я не могу/хочу в данный момент исправлять) в качестве вспомогательного средства. В этом случае вместо импорта функций из себя же, придется создать отдельный стандартный модуль с функциями-пустышками с необходимыми прототипами. В свойствах Add-in'а необходимо выбрать события компиляции (before linking) и прописать там BATCH файл который будет заменять модуль пустышку на модуль переходник. Модуль переходник такой же тривиальный, следует только учесть что символы будут вида ?FuncName@ModuleName@@AAGXXZ (декорированные) и выполняет функции прыжка на необходимые linked символы.

К примеру все тоже самое как и в первом примере, только без экспорта.
Модуль изменится на:
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
Option Explicit

#If INIDE Then

Public Declare Sub WriteToConsole Lib "..\static_lib\testlib\release\testdll" ( _
                   ByVal pszValue As Long)
Public Declare Sub ReadFromConsole Lib "..\static_lib\testlib\release\testdll" ( _
                   ByVal ppszValue As Long)
                   
Public Declare Function AllocConsole Lib "kernel32" () As Long
Public Declare Function FreeConsole Lib "kernel32" () As Long
Public Declare Function SetDllDirectoryW Lib "kernel32" ( _
                        ByVal pszString As Long) As Long
                            
#Else

Public Sub WriteToConsole( _
           ByVal pszValue As Long)
End Sub

Public Sub ReadFromConsole( _
           ByVal pszValue As Long)
End Sub

#End If


Здесь просто вызываются функции пустышки при INIDE = False (компиляции). Также создается простой редиректор:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
format MS COFF

section '.text' code readable executable

WriteToConsole equ ?WriteToConsole@@YGXPAG@Z
ReadFromConsole equ ?ReadFromConsole@@YGXPAPAG@Z

extrn WriteToConsole
extrn ReadFromConsole

public ?WriteToConsole@modStaticLib@@AAGXXZ
public ?ReadFromConsole@modStaticLib@@AAGXXZ

?WriteToConsole@modStaticLib@@AAGXXZ:
jmp WriteToConsole

?ReadFromConsole@modStaticLib@@AAGXXZ:
jmp ReadFromConsole


modStaticLib здесь - имя заменяемого модуля. Следующий шаг - замена оригинального modStaticLib.OBJ на редиректор перед линковкой:
Код: sql
1.
2.
del modStaticLib.obj
copy asm\modStaticLib.obj modStaticLib.obj


И установить событие перед линковкой:

Последний шаг - удалить экспорты которые были добавлены в предыдущем способе:
Код: sql
1.
2.
[VBCompiler]
LinkSwitches=OleAut32.lib ..\init_runtime.obj ..\static_lib\testlib\Release\testlib.lib -SUBSYSTEM:CONSOLE -ENTRY:mainCRTStartup


Все, можно компилировать и получить монолитный файл:

Все файлы прикладываю.
...
Рейтинг: 0 / 0
Линковка статических библиотек OBJ/LIB к VB-экзешнику
    #39765077
Eolt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cпасибо большое! Буду пробовать.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Линковка статических библиотек OBJ/LIB к VB-экзешнику
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]