Discussion of using mdfunc to wrap dll

Discuss Autohotkey related topics here. Not a place to share code.
Forum rules
Discuss Autohotkey related topics here. Not a place to share code.
cumulonimbus
Posts: 4
Joined: 19 Aug 2023, 13:37

Discussion of using mdfunc to wrap dll

18 Apr 2024, 07:29

I found the use of mdfunc in the forum, so I tried to use it to package dlls.


This libarchive function, the role is to extract the compressed package to the object.
mdfunc will libarchive api initialized to global variables, compared to the common dll packaging method, it is more efficient.

Code: Select all

archive_init() {
	global
	LoadLibraryW(A_AhkDir "\libcrypto-1_1-x64.dll")
	archive_mod := LoadLibraryW(A_AhkDir "\libarchive.dll")

	archive_read_new := mdfunc(GetProcAddress(archive_mod, "archive_read_new"), 8)
	archive_read_free := mdfunc(GetProcAddress(archive_mod, "archive_read_free"), [8, 5])
	archive_read_close := mdfunc(GetProcAddress(archive_mod, "archive_read_close"), [8, 5])

	archive_read_support_filter_all := mdfunc(GetProcAddress(archive_mod, "archive_read_support_filter_all"), [8, 8])
	archive_read_support_format_all := mdfunc(GetProcAddress(archive_mod, "archive_read_support_format_all"), [8, 8])

	archive_read_open_memory := mdfunc(GetProcAddress(archive_mod, "archive_read_open_memory"), [8, 8, 8, 5])
	archive_read_open_filename_w := mdfunc(GetProcAddress(archive_mod, "archive_read_open_filename_w"), [8, 11, 5, 5])
	archive_read_data_skip := mdfunc(GetProcAddress(archive_mod, "archive_read_data_skip"), [8, 5])
	archive_entry_filetype := mdfunc(GetProcAddress(archive_mod, "archive_entry_filetype"), [8, 5])
	archive_entry_size := mdfunc(GetProcAddress(archive_mod, "archive_entry_size"), [8, 5])
	archive_read_data := mdfunc(GetProcAddress(archive_mod, "archive_read_data"), [8, 8, 8, 8])
	archive_read_next_header := mdfunc(GetProcAddress(archive_mod, "archive_read_next_header"), [8, 8, 5])
	archive_entry_pathname_w := DynaCall(GetProcAddress(archive_mod, "archive_entry_pathname_w"), 'w==t')
}

archive(pt) {
	static _ := archive_init()
	a := archive_read_new()
	archive_read_support_filter_all(a)
	archive_read_support_format_all(a)

	if 0 = (pt is Buffer
		? archive_read_open_memory(a, pt.ptr, pt.size)
		: archive_read_open_filename_w(a, pt, 10240))
	{
		t := UMap()
		entry := 0
		ptr := GetVar(entry)
		while 0 = archive_read_next_header(a, ptr)
		{
			switch archive_entry_filetype(entry)
			{
				case 0x8000:
					sz := archive_entry_size(entry)
					buf := Buffer(sz)
					archive_read_data(a, buf.ptr, sz)
					t[archive_entry_pathname_w(entry)] := buf
				case 0x4000: ; dir
					t[archive_entry_pathname_w(entry)] := 0
			}

		}
	}
	archive_read_close(a)
	archive_read_free(a)
	return t ?? 0
}



I used the same method to package sqlite3. the old method to read a 70,000 rows * 8 columns of the database to the object, it takes 1.9 seconds. The new method takes only 0.6 seconds.


I would very much like to start more discussion on mdfunc. Are there more similar ways of using it or what are its drawbacks and what are the things to be aware of.


[Mod action: Moved topic from “AutoHotkey Development” which is for discussing the future of the AutoHotkey language itself.]

Return to “General Discussion”

Who is online

Users browsing this forum: No registered users and 11 guests