├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── dylib_386_test.go ├── dylib_amd64_test.go ├── dylib_posix.go ├── dylib_windows.go ├── floatpatch ├── asmTest_test.go ├── asmtestdll │ ├── Project12.dpr │ └── Project12.dproj ├── floatResultPatch.go ├── floatResultPatch_386.s └── floatResultPatch_amd64.s └── testdll ├── testdll.dpr └── testdll.dproj /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pas linguist-language=go 2 | *.inc linguist-language=go -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Uncomment these types if you want even more clean repository. But be careful. 2 | # It can make harm to an existing project source. Read explanations below. 3 | # 4 | # Resource files are binaries containing manifest, project icon and version info. 5 | # They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files. 6 | #*.res 7 | # 8 | # Type library file (binary). In old Delphi versions it should be stored. 9 | # Since Delphi 2009 it is produced from .ridl file and can safely be ignored. 10 | #*.tlb 11 | # 12 | # Diagram Portfolio file. Used by the diagram editor up to Delphi 7. 13 | # Uncomment this if you are not using diagrams or use newer Delphi version. 14 | #*.ddp 15 | # 16 | # Visual LiveBindings file. Added in Delphi XE2. 17 | # Uncomment this if you are not using LiveBindings Designer. 18 | #*.vlb 19 | # 20 | # Deployment Manager configuration file for your project. Added in Delphi XE2. 21 | # Uncomment this if it is not mobile development and you do not use remote debug feature. 22 | #*.deployproj 23 | # 24 | # C++ object files produced when C/C++ Output file generation is configured. 25 | # Uncomment this if you are not using external objects (zlib library for example). 26 | #*.obj 27 | # 28 | 29 | # Delphi compiler-generated binaries (safe to delete) 30 | *.exe 31 | *.dll 32 | *.bpl 33 | *.bpi 34 | *.dcp 35 | *.so 36 | *.apk 37 | *.drc 38 | *.map 39 | *.dres 40 | *.rsm 41 | *.tds 42 | *.dcu 43 | *.lib 44 | *.a 45 | *.o 46 | *.ocx 47 | *.app 48 | *.dylib 49 | 50 | # Delphi autogenerated files (duplicated info) 51 | *.cfg 52 | *.hpp 53 | *Resource.rc 54 | 55 | # Delphi local files (user-specific info) 56 | *.local 57 | *.identcache 58 | *.projdata 59 | *.tvsconfig 60 | *.dsk 61 | 62 | # Delphi history and backups 63 | __history/ 64 | __recovery/ 65 | *.~* 66 | 67 | # Castalia statistics file (since XE7 Castalia is distributed with Delphi) 68 | *.stat 69 | /.vscode 70 | /.idea 71 | /bin/styles 72 | /bin/win64 73 | /bin/win32 74 | /Librarys 75 | *.she 76 | *.vsf 77 | *.ini 78 | *.td 79 | /vcl/dylib/testdll 80 | *.bak 81 | /bin 82 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | *通用的跨平台动态连接库调用, 支持 dll、so、dylib。 Move from: github.com/ying32/govcl/vcl/dylib* 2 | 3 | *Universal cross-platform dynamic link library call, support dll, so, dylib. Move from: github.com/ying32/govcl/vcl/dylib* 4 | 5 | ### 简介 6 | 7 | dylib是从govcl的api包中分离出来,可以方便其它使用。 8 | dylib实现了一个通用的共享库调用,可以在windows、linux、macOS下不需要任何改变实现通用。 9 | Window下使用syscall.NewLazyDLL加载dll,linux与macOS下使用dlopen加载,然后使用dlsym来获取, 10 | 通过封装,使用接口与Windows下的一模一样,如此达到通用,最多实现12个参数的过程。 11 | 12 | ### 使用方法 13 | 14 | ```go 15 | 16 | import "github.com/ying32/dylib" 17 | 18 | var ( 19 | lib = dylib.NewLazyDLL("xxx.dll") // 或者 dylib.NewLazyDLL("xxx.so") 或者 dylib.NewLazyDLL("xxx.dylib") 20 | _Func1 = lib.NewProc("Func1") 21 | _Func2 = lib.NewProc("Func2") 22 | _Func3 = lib.NewProc("Func3") 23 | ) 24 | 25 | // 普通的 26 | func Func1(a1, a2 int) int { 27 | r, _, _ := _Func1.Call(uintptr(a1), uintptr(a2)) 28 | return int(r) 29 | } 30 | 31 | // 浮点类型的, 切记不要直接在共享库中直接返回浮点类型的,要返回记得使用指针参数进行传递 32 | func Func2() float32 { 33 | var f float32 34 | _Func2.Call(uintptr(unsafe.Pointer(&f))) 35 | return f 36 | } 37 | 38 | // 如果是外部的共享库返回float32或者float64则另使用补丁方式,暂时不支持arm 39 | // import "github.com/ying32/dylib/floatpatch" 40 | // float32 41 | func Func2() float32 { 42 | _Func2.Call() 43 | return floatpatch.Getfloat32() // 注,在此函数前面不要调用其他函数了,不然就获取不到结果 44 | } 45 | 46 | // float64 47 | func Func2() float64 { 48 | _Func2.Call() 49 | return floatpatch.Getfloat64() // 注,在此函数前面不要调用其他函数了,不然就获取不到结果 50 | } 51 | 52 | 53 | // 结构类型的, 切记不要直接在共享库中直接返回结构类型,要返回记得使用指针参数进行传递 54 | // 参数的传递也要使用指针类型传递 55 | type TPoint struct { 56 | X int32 57 | Y int32 58 | } 59 | 60 | func Func3(p1 TPoint) TPoint { 61 | var pret TPoint 62 | _Func3.Call(uintptr(unsafe.Pointer(&p1)), uintptr(unsafe.Pointer(&pret))) 63 | return pret 64 | } 65 | 66 | 67 | 68 | ``` 69 | 70 | ### 需要特别注意的事情 71 | 72 | * 1、不要在共享库中返回float类的,不然会被go强转,如需使用可选择使用参数指针传递(注:如是外部无法修改的共享库,则使用上面的补丁方式)。 73 | * 2、在参数或者返回值类型中需要注意: 在x86库中应该尽量避免直接返回或者使用size>=8的类型,如需使用最好选择参数指针替代,以保持x86跟x64一致性。 74 | 75 | 76 | 77 | ### MySyscall 实现 78 | 在被调用的共享库中如果导出了“MySyscall”函数,则会使用此函数来call, 一般导出此函数的目的是为了在共享库中捕获异常,不然一但共享库中出现异常 79 | 程序就挂了。 80 | 81 | ```pascal 82 | // 一个Delphi的"MySyscall"实现例程: 83 | 84 | type 85 | TSyscall0 = function: UInt64; stdcall; 86 | TSyscall1 = function(A1: Pointer): UInt64; stdcall; 87 | TSyscall2 = function(A1, A2: Pointer): UInt64; stdcall; 88 | TSyscall3 = function(A1, A2, A3: Pointer): UInt64; stdcall; 89 | TSyscall4 = function(A1, A2, A3, A4: Pointer): UInt64; stdcall; 90 | TSyscall5 = function(A1, A2, A3, A4, A5: Pointer): UInt64; stdcall; 91 | TSyscall6 = function(A1, A2, A3, A4, A5, A6: Pointer): UInt64; stdcall; 92 | TSyscall7 = function(A1, A2, A3, A4, A5, A6, A7: Pointer): UInt64; stdcall; 93 | TSyscall8 = function(A1, A2, A3, A4, A5, A6, A7, A8: Pointer): UInt64; stdcall; 94 | TSyscall9 = function(A1, A2, A3, A4, A5, A6, A7, A8, A9: Pointer): UInt64; stdcall; 95 | TSyscall10 = function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10: Pointer): UInt64; stdcall; 96 | TSyscall11 = function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11: Pointer): UInt64; stdcall; 97 | TSyscall12 = function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: Pointer): UInt64; stdcall; 98 | 99 | function MySyscall(AProc: Pointer; ALen: NativeInt; A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: Pointer): UInt64; stdcall; 100 | begin 101 | Result := 0; 102 | if AProc = nil then 103 | Exit; 104 | try 105 | case ALen of 106 | 0: Result := TSyscall0(AProc)(); 107 | 1: Result := TSyscall1(AProc)(A1); 108 | 2: Result := TSyscall2(AProc)(A1, A2); 109 | 3: Result := TSyscall3(AProc)(A1, A2, A3); 110 | 4: Result := TSyscall4(AProc)(A1, A2, A3, A4); 111 | 5: Result := TSyscall5(AProc)(A1, A2, A3, A4, A5); 112 | 6: Result := TSyscall6(AProc)(A1, A2, A3, A4, A5, A6); 113 | 7: Result := TSyscall7(AProc)(A1, A2, A3, A4, A5, A6, A7); 114 | 8: Result := TSyscall8(AProc)(A1, A2, A3, A4, A5, A6, A7, A8); 115 | 9: Result := TSyscall9(AProc)(A1, A2, A3, A4, A5, A6, A7, A8, A9); 116 | 10: Result := TSyscall10(AProc)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); 117 | 11: Result := TSyscall11(AProc)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); 118 | 12: Result := TSyscall12(AProc)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); 119 | else 120 | Exit; 121 | end; 122 | except 123 | on E: Exception do 124 | begin 125 | Writeln('Syscall', ALen, ' Error: ', E.Message); 126 | end; 127 | end; 128 | end; 129 | 130 | ``` 131 | 132 | -------------------------------------------------------------------------------- /dylib_386_test.go: -------------------------------------------------------------------------------- 1 | package dylib 2 | 3 | import ( 4 | "runtime" 5 | "testing" 6 | ) 7 | 8 | func ToUInt64(r1, r2 uintptr) uint64 { 9 | ret := uint64(r2) 10 | ret = uint64(ret<<32) + uint64(r1) 11 | return ret 12 | } 13 | 14 | func TestAll(t *testing.T) { 15 | testdll := NewLazyDLL("testdll_" + runtime.GOARCH) 16 | defer testdll.Close() 17 | 18 | var int64Max int64 = 9223372036854775807 19 | var uint64Max uint64 = 18446744073709551615 20 | var int64Val1 int64 = 0xFF2233445500 21 | var int64Val2 int64 = 0xFF6677889900 22 | 23 | t.Log(int64Max, uint64Max, int64Val1, int64Val2) 24 | t.Log("--------------------------------------------------------------") 25 | 26 | // 无参数,但返回值为int64 27 | ResultValue := testdll.NewProc("ResultValue") 28 | 29 | r1, r2, _ := ResultValue.Call() 30 | t.Log("r1:", r1, ", r2:", r2) 31 | if int64(ToUInt64(r1, r2)) == int64Max { 32 | t.Log("测试结果正确") 33 | } else { 34 | t.Fatal("测试结果错误,正确值为", int64Max, ",当前值:", int64(ToUInt64(r1, r2))) 35 | } 36 | 37 | // 2个参数,类型为int64,返回为uint64 38 | ResultValAndParam := testdll.NewProc("ResultValAndParam") 39 | r1, r2, _ = ResultValAndParam.Call(uintptr(int64Val1), uintptr(int64Val1>>32), uintptr(int64Val2), uintptr(int64Val2>>32)) 40 | t.Log("r1:", r1, ", r2:", r2) 41 | if ToUInt64(r1, r2) == uint64Max { 42 | t.Log("测试结果正确") 43 | } else { 44 | t.Fatal("测试结果错误,正确值为", uint64Max, ",当前值:", ToUInt64(r1, r2)) 45 | } 46 | 47 | t.Log("------------------------------32bit-----------------------------") 48 | 49 | var intMax int32 = 2147483647 50 | var uintMax uint32 = 4294967295 51 | var intVal1 int32 = 0x0F112233 52 | var intVal2 int32 = 0x0F445566 53 | 54 | t.Log(intMax, uintMax, intVal1, intVal2) 55 | t.Log("--------------------------------------------------------------") 56 | 57 | // 无参数,但返回值为int64 58 | ResultValue32 := testdll.NewProc("ResultValue32") 59 | 60 | r1, r2, _ = ResultValue32.Call() 61 | t.Log("r1:", r1, ", r2:", r2) 62 | if int32(r1) == intMax { 63 | t.Log("测试结果正确") 64 | } else { 65 | t.Fatal("测试结果错误,正确值为", intMax, ",当前值:", int32(r1)) 66 | } 67 | 68 | // 2个参数,类型为int64,返回为uint64 69 | ResultValAndParam32 := testdll.NewProc("ResultValAndParam32") 70 | r1, r2, _ = ResultValAndParam32.Call(uintptr(intVal1), uintptr(intVal2)) 71 | t.Log("r1:", r1, ", r2:", r2) 72 | if uint32(r1) == uintMax { 73 | t.Log("测试结果正确") 74 | } else { 75 | t.Fatal("测试结果错误,正确值为", uintMax, ",当前值:", uint32(r1)) 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /dylib_amd64_test.go: -------------------------------------------------------------------------------- 1 | package dylib 2 | 3 | import ( 4 | "runtime" 5 | "testing" 6 | ) 7 | 8 | func TestAll(t *testing.T) { 9 | testdll := NewLazyDLL("testdll_" + runtime.GOARCH) 10 | defer testdll.Close() 11 | 12 | t.Log("----------------------64bit----------------------------------") 13 | var int64Max int64 = 9223372036854775807 14 | var uint64Max uint64 = 18446744073709551615 15 | var int64Val1 int64 = 0xFF2233445500 16 | var int64Val2 int64 = 0xFF6677889900 17 | 18 | t.Log(int64Max, uint64Max, int64Val1, int64Val2) 19 | t.Log("--------------------------------------------------------------") 20 | 21 | // 无参数,但返回值为int64 22 | ResultValue := testdll.NewProc("ResultValue") 23 | 24 | r1, r2, _ := ResultValue.Call() 25 | t.Log("r1:", r1, ", r2:", r2) 26 | if int64(r1) == int64Max { 27 | t.Log("测试结果正确") 28 | } else { 29 | t.Fatal("测试结果错误,正确值为", int64Max, ",当前值:", int64(r1)) 30 | } 31 | 32 | // 2个参数,类型为int64,返回为uint64 33 | ResultValAndParam := testdll.NewProc("ResultValAndParam") 34 | r1, r2, _ = ResultValAndParam.Call(uintptr(int64Val1), uintptr(int64Val2)) 35 | t.Log("r1:", r1, ", r2:", r2) 36 | if uint64(r1) == uint64Max { 37 | t.Log("测试结果正确") 38 | } else { 39 | t.Fatal("测试结果错误,正确值为", uint64Max, ",当前值:", uint64(r1)) 40 | } 41 | 42 | t.Log("------------------------------32bit-----------------------------") 43 | 44 | var intMax int32 = 2147483647 45 | var uintMax uint32 = 4294967295 46 | var intVal1 int32 = 0x0F112233 47 | var intVal2 int32 = 0x0F445566 48 | 49 | t.Log(intMax, uintMax, intVal1, intVal2) 50 | t.Log("--------------------------------------------------------------") 51 | 52 | // 无参数,但返回值为int64 53 | ResultValue32 := testdll.NewProc("ResultValue32") 54 | 55 | r1, r2, _ = ResultValue32.Call() 56 | t.Log("r1:", r1, ", r2:", r2) 57 | if int32(r1) == intMax { 58 | t.Log("测试结果正确") 59 | } else { 60 | t.Fatal("测试结果错误,正确值为", intMax, ",当前值:", int32(r1)) 61 | } 62 | 63 | // 2个参数,类型为int64,返回为uint64 64 | ResultValAndParam32 := testdll.NewProc("ResultValAndParam32") 65 | r1, r2, _ = ResultValAndParam32.Call(uintptr(intVal1), uintptr(intVal2)) 66 | t.Log("r1:", r1, ", r2:", r2) 67 | if uint32(r1) == uintMax { 68 | t.Log("测试结果正确") 69 | } else { 70 | t.Fatal("测试结果错误,正确值为", uintMax, ",当前值:", uint32(r1)) 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /dylib_posix.go: -------------------------------------------------------------------------------- 1 | // +build !windows 2 | // +build cgo 3 | 4 | package dylib 5 | 6 | /* 7 | #cgo LDFLAGS: -ldl 8 | 9 | //#cgo LDFLAGS: -L. -Wl,-rpath,${SRCDIR} -llcl 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | static uintptr_t libOpen(const char* path) { 18 | void* h = dlopen(path, RTLD_LAZY|RTLD_GLOBAL); // RTLD_LAZY RTLD_NOW |RTLD_GLOBAL 19 | if (h == NULL) { 20 | printf("dlopen err: %s\n", (char*)dlerror()); 21 | return 0; 22 | } 23 | return (uintptr_t)h; 24 | } 25 | 26 | static uintptr_t libLookup(uintptr_t h, const char* name) { 27 | void* r = dlsym((void*)h, name); 28 | if (r == NULL) { 29 | //printf("dlsym err: %s\n", (char*)dlerror()); 30 | return 0; 31 | } 32 | return (uintptr_t)r; 33 | } 34 | 35 | static void libClose(uintptr_t h) { 36 | if(h != 0) { 37 | dlclose((void*)h); 38 | } 39 | } 40 | 41 | 42 | static uint64_t Syscall0(void* addr) { 43 | return ((uint64_t(*)())addr)(); 44 | } 45 | 46 | static uint64_t Syscall1(void* addr, void* p1) { 47 | return ((uint64_t(*)(void*))addr)(p1); 48 | } 49 | 50 | static uint64_t Syscall2(void* addr, void* p1, void* p2) { 51 | return ((uint64_t(*)(void*,void*))addr)(p1, p2); 52 | } 53 | 54 | static uint64_t Syscall3(void* addr, void* p1, void* p2, void* p3) { 55 | return ((uint64_t(*)(void*,void*,void*))addr)(p1, p2, p3); 56 | } 57 | 58 | static uint64_t Syscall4(void* addr, void* p1, void* p2, void* p3, void* p4) { 59 | return ((uint64_t(*)(void*,void*,void*,void*))addr)(p1, p2, p3, p4); 60 | } 61 | 62 | static uint64_t Syscall5(void* addr, void* p1, void* p2, void* p3, void* p4, void* p5) { 63 | return ((uint64_t(*)(void*,void*,void*,void*,void*))addr)(p1, p2, p3, p4, p5); 64 | } 65 | 66 | static uint64_t Syscall6(void* addr, void* p1, void* p2, void* p3, void* p4, void* p5, void* p6) { 67 | return ((uint64_t(*)(void*,void*,void*,void*,void*,void*))addr)(p1, p2, p3, p4, p5, p6); 68 | } 69 | 70 | static uint64_t Syscall7(void* addr, void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void *p7) { 71 | return ((uint64_t(*)(void*,void*,void*,void*,void*,void*, void*))addr)(p1, p2, p3, p4, p5, p6, p7); 72 | } 73 | 74 | static uint64_t Syscall8(void* addr, void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void *p7, void *p8) { 75 | return ((uint64_t(*)(void*,void*,void*,void*,void*,void*,void*,void*))addr)(p1, p2, p3, p4, p5, p6,p7,p8); 76 | } 77 | 78 | static uint64_t Syscall9(void* addr, void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void *p7, void *p8, void *p9) { 79 | return ((uint64_t(*)(void*,void*,void*,void*,void*,void*,void*,void*,void*))addr)(p1, p2, p3, p4, p5, p6,p7,p8,p9); 80 | } 81 | 82 | static uint64_t Syscall10(void* addr, void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void *p7, void *p8, void *p9, void *p10) { 83 | return ((uint64_t(*)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*))addr)(p1, p2, p3, p4, p5, p6,p7,p8,p9,p10); 84 | } 85 | 86 | static uint64_t Syscall11(void* addr, void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void *p7, void *p8, void *p9, void *p10, void *p11) { 87 | return ((uint64_t(*)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*,void*))addr)(p1, p2, p3, p4, p5, p6,p7,p8,p9,p10,p11); 88 | } 89 | 90 | static uint64_t Syscall12(void* addr, void* p1, void* p2, void* p3, void* p4, void* p5, void* p6, void *p7, void *p8, void *p9, void *p10, void *p11, void *p12) { 91 | return ((uint64_t(*)(void*,void*,void*,void*,void*,void*,void*,void*,void*,void*,void*,void*))addr)(p1, p2, p3, p4, p5, p6,p7,p8,p9,p10,p11,p12); 92 | } 93 | 94 | */ 95 | import "C" 96 | 97 | import ( 98 | "errors" 99 | "fmt" 100 | "os" 101 | "os/exec" 102 | "path/filepath" 103 | "runtime" 104 | "strconv" 105 | "sync" 106 | "syscall" 107 | "unsafe" 108 | ) 109 | 110 | type LazyDLL struct { 111 | mu sync.Mutex 112 | handle C.uintptr_t 113 | err error 114 | Name string 115 | // 加了异常处理的 116 | mySyscall *LazyProc 117 | } 118 | 119 | func NewLazyDLL(name string) *LazyDLL { 120 | 121 | m := new(LazyDLL) 122 | m.Name = name 123 | m.mu.Lock() 124 | defer m.mu.Unlock() 125 | 126 | cPath := (*C.char)(C.malloc(C.PATH_MAX + 1)) 127 | defer C.free(unsafe.Pointer(cPath)) 128 | 129 | cRelName := C.CString(m.libFullPath(name)) 130 | defer C.free(unsafe.Pointer(cRelName)) 131 | 132 | if C.realpath(cRelName, cPath) == nil { 133 | m.handle = C.libOpen(cRelName) 134 | } else { 135 | m.handle = C.libOpen(cPath) 136 | } 137 | if m.handle == 0 { 138 | m.err = fmt.Errorf("dlopen(\"%s\"), failed.", name) 139 | return m 140 | } 141 | // 导入调用的, 实现一个动态调用call的,主要是为了解决异常问题 142 | m.mySyscall = m.NewProc("MySyscall") 143 | if m.mySyscall.Find() != nil { 144 | m.mySyscall = nil 145 | } 146 | 147 | return m 148 | } 149 | 150 | func fileExists(path string) bool { 151 | _, err := os.Stat(path) 152 | if err == nil { 153 | return true 154 | } 155 | if os.IsNotExist(err) { 156 | return false 157 | } 158 | return false 159 | } 160 | 161 | func (l *LazyDLL) libFullPath(name string) string { 162 | if runtime.GOOS == "darwin" { 163 | file, _ := exec.LookPath(os.Args[0]) 164 | libPath := filepath.Dir(file) + "/" + name 165 | if fileExists(libPath) { 166 | return libPath 167 | } 168 | } 169 | return name 170 | } 171 | 172 | func (l *LazyDLL) Load() error { 173 | return l.err 174 | } 175 | 176 | func (l *LazyDLL) NewProc(name string) *LazyProc { 177 | p := new(LazyProc) 178 | p.Name = name 179 | p.lzdll = l 180 | return p 181 | } 182 | 183 | func (l *LazyDLL) Close() { 184 | C.libClose(l.handle) 185 | } 186 | 187 | func (d *LazyDLL) call(proc *LazyProc, a ...uintptr) (r1, r2 uintptr, lastErr error) { 188 | // 没到找到我封装的那个系统函数,就使用原始的 189 | if d.mySyscall == nil { 190 | return proc.CallOriginal(a...) 191 | } 192 | addr := proc.Addr() 193 | if addr != 0 { 194 | pLen := uintptr(len(a)) 195 | switch pLen { 196 | case 0: 197 | return d.mySyscall.CallOriginal(addr, pLen) 198 | case 1: 199 | return d.mySyscall.CallOriginal(addr, pLen, a[0]) 200 | case 2: 201 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1]) 202 | case 3: 203 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2]) 204 | case 4: 205 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3]) 206 | case 5: 207 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3], a[4]) 208 | case 6: 209 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5]) 210 | case 7: 211 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6]) 212 | case 8: 213 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]) 214 | case 9: 215 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) 216 | case 10: 217 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]) 218 | case 11: 219 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]) 220 | case 12: 221 | return d.mySyscall.CallOriginal(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) 222 | default: 223 | panic("Call " + proc.Name + " with too many arguments " + strconv.Itoa(len(a)) + ".") 224 | } 225 | } 226 | return 0, 0, syscall.EINVAL 227 | } 228 | 229 | type LazyProc struct { 230 | mu sync.Mutex 231 | p uintptr 232 | Name string 233 | lzdll *LazyDLL 234 | } 235 | 236 | func (p *LazyProc) Addr() uintptr { 237 | err := p.Find() 238 | if err != nil { 239 | fmt.Println(err) 240 | } 241 | return p.p 242 | } 243 | 244 | func (p *LazyProc) Find() error { 245 | if p.p == 0 { 246 | p.mu.Lock() 247 | defer p.mu.Unlock() 248 | cRelName := C.CString(p.Name) 249 | defer C.free(unsafe.Pointer(cRelName)) 250 | p.p = uintptr(C.libLookup(p.lzdll.handle, cRelName)) 251 | // 这里不管了 252 | } 253 | if p.p == 0 { 254 | return errors.New("proc \"" + p.Name + "\" not find.") 255 | } 256 | return nil 257 | } 258 | 259 | func toPtr(a uintptr) unsafe.Pointer { 260 | return unsafe.Pointer(a) 261 | } 262 | 263 | func (p *LazyProc) Call(a ...uintptr) (uintptr, uintptr, error) { 264 | return p.lzdll.call(p, a...) 265 | } 266 | 267 | func (p *LazyProc) CallOriginal(a ...uintptr) (r1, r2 uintptr, lastErr error) { 268 | err := p.Find() 269 | if err != nil { 270 | fmt.Println(err) 271 | return 0, 0, syscall.EINVAL 272 | } 273 | var ret C.uint64_t 274 | switch len(a) { 275 | case 0: 276 | ret = C.Syscall0(unsafe.Pointer(p.p)) 277 | case 1: 278 | ret = C.Syscall1(toPtr(p.p), toPtr(a[0])) 279 | case 2: 280 | ret = C.Syscall2(toPtr(p.p), toPtr(a[0]), toPtr(a[1])) 281 | case 3: 282 | ret = C.Syscall3(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2])) 283 | case 4: 284 | ret = C.Syscall4(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3])) 285 | case 5: 286 | ret = C.Syscall5(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3]), toPtr(a[4])) 287 | case 6: 288 | ret = C.Syscall6(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3]), toPtr(a[4]), toPtr(a[5])) 289 | case 7: 290 | ret = C.Syscall7(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3]), toPtr(a[4]), toPtr(a[5]), toPtr(a[6])) 291 | case 8: 292 | ret = C.Syscall8(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3]), toPtr(a[4]), toPtr(a[5]), toPtr(a[6]), toPtr(a[7])) 293 | case 9: 294 | ret = C.Syscall9(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3]), toPtr(a[4]), toPtr(a[5]), toPtr(a[6]), toPtr(a[7]), toPtr(a[8])) 295 | case 10: 296 | ret = C.Syscall10(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3]), toPtr(a[4]), toPtr(a[5]), toPtr(a[6]), toPtr(a[7]), toPtr(a[8]), toPtr(a[9])) 297 | case 11: 298 | ret = C.Syscall11(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3]), toPtr(a[4]), toPtr(a[5]), toPtr(a[6]), toPtr(a[7]), toPtr(a[8]), toPtr(a[9]), toPtr(a[10])) 299 | case 12: 300 | ret = C.Syscall12(toPtr(p.p), toPtr(a[0]), toPtr(a[1]), toPtr(a[2]), toPtr(a[3]), toPtr(a[4]), toPtr(a[5]), toPtr(a[6]), toPtr(a[7]), toPtr(a[8]), toPtr(a[9]), toPtr(a[10]), toPtr(a[11])) 301 | 302 | default: 303 | panic("Call " + p.Name + " with too many arguments " + strconv.Itoa(len(a)) + ".") 304 | } 305 | return uintptr(ret), uintptr(ret >> 32), nil 306 | } 307 | -------------------------------------------------------------------------------- /dylib_windows.go: -------------------------------------------------------------------------------- 1 | package dylib 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "syscall" 7 | ) 8 | 9 | type LazyDLL struct { 10 | *syscall.LazyDLL 11 | // 加了异常处理的 12 | mySyscall *syscall.LazyProc 13 | } 14 | 15 | func NewLazyDLL(name string) *LazyDLL { 16 | l := new(LazyDLL) 17 | l.LazyDLL = syscall.NewLazyDLL(name) 18 | if err := l.Load(); err != nil { 19 | return l 20 | } 21 | // 导入调用的, 实现一个动态调用call的,主要是为了解决异常问题 22 | l.mySyscall = l.LazyDLL.NewProc("MySyscall") 23 | if l.mySyscall.Find() != nil { 24 | l.mySyscall = nil 25 | } 26 | return l 27 | } 28 | 29 | // 定义一个相同的 30 | type LazyProc struct { 31 | lzProc *syscall.LazyProc 32 | lzdll *LazyDLL 33 | } 34 | 35 | func (d *LazyDLL) NewProc(name string) *LazyProc { 36 | l := new(LazyProc) 37 | l.lzProc = d.LazyDLL.NewProc(name) 38 | l.lzdll = d 39 | return l 40 | } 41 | 42 | func (d *LazyDLL) Close() { 43 | if d.Handle() != 0 { 44 | syscall.FreeLibrary(syscall.Handle(d.Handle())) 45 | } 46 | } 47 | 48 | func (d *LazyDLL) call(proc *LazyProc, a ...uintptr) (r1, r2 uintptr, lastErr error) { 49 | // 没到找到我封装的那个系统函数,就使用原始的 50 | if d.mySyscall == nil { 51 | return proc.CallOriginal(a...) 52 | } 53 | err := proc.Find() 54 | if err != nil { 55 | fmt.Println("proc \"" + proc.lzProc.Name + "\" not find.") 56 | return 0, 0, syscall.EINVAL 57 | } 58 | addr := proc.Addr() 59 | if addr != 0 { 60 | pLen := uintptr(len(a)) 61 | switch pLen { 62 | case 0: 63 | return d.mySyscall.Call(addr, pLen) 64 | case 1: 65 | return d.mySyscall.Call(addr, pLen, a[0]) 66 | case 2: 67 | return d.mySyscall.Call(addr, pLen, a[0], a[1]) 68 | case 3: 69 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2]) 70 | case 4: 71 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3]) 72 | case 5: 73 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3], a[4]) 74 | case 6: 75 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5]) 76 | case 7: 77 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6]) 78 | case 8: 79 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]) 80 | case 9: 81 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]) 82 | case 10: 83 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]) 84 | case 11: 85 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10]) 86 | case 12: 87 | return d.mySyscall.Call(addr, pLen, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11]) 88 | default: 89 | panic("Call " + proc.lzProc.Name + " with too many arguments " + strconv.Itoa(len(a)) + ".") 90 | } 91 | } 92 | return 0, 0, syscall.EINVAL 93 | } 94 | 95 | func (p *LazyProc) Addr() uintptr { 96 | return p.lzProc.Addr() 97 | } 98 | 99 | func (p *LazyProc) Find() error { 100 | return p.lzProc.Find() 101 | } 102 | 103 | func (p *LazyProc) Call(a ...uintptr) (r1, r2 uintptr, lastErr error) { 104 | return p.lzdll.call(p, a...) 105 | } 106 | 107 | func (p *LazyProc) CallOriginal(a ...uintptr) (r1, r2 uintptr, lastErr error) { 108 | return p.lzProc.Call(a...) 109 | } 110 | -------------------------------------------------------------------------------- /floatpatch/asmTest_test.go: -------------------------------------------------------------------------------- 1 | package floatpatch 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/ying32/dylib" 7 | ) 8 | 9 | var ( 10 | libTest = dylib.NewLazyDLL("Project12.dll") 11 | _testFloat32_MaxValue = libTest.NewProc("testFloat32_MaxValue") 12 | _testFloat32_MinValue = libTest.NewProc("testFloat32_MinValue") 13 | _testFloat32_Epsilon = libTest.NewProc("testFloat32_Epsilon") 14 | 15 | _testFloat64_MaxValue = libTest.NewProc("testFloat64_MaxValue") 16 | _testFloat64_MinValue = libTest.NewProc("testFloat64_MinValue") 17 | _testFloat64_Epsilon = libTest.NewProc("testFloat64_Epsilon") 18 | ) 19 | 20 | func TestASM(t *testing.T) { 21 | 22 | t.Log("---------------float32----------------") 23 | /* 24 | Epsilon:Single = 1.4012984643248170709e-45; 25 | MaxValue:Single = 340282346638528859811704183484516925440.0; 26 | MinValue:Single = -340282346638528859811704183484516925440.0; 27 | PositiveInfinity:Single = 1.0 / 0.0; 28 | NegativeInfinity:Single = -1.0 / 0.0; 29 | NaN:Single = 0.0 / 0.0; 30 | */ 31 | 32 | t.Log("testFloat32_MaxValue:", testFloat32_MaxValue()) 33 | t.Log("testFloat32_MinValue:", testFloat32_MinValue()) 34 | t.Log("testFloat32_Epsilon:", testFloat32_Epsilon()) 35 | 36 | t.Log("---------------float64----------------") 37 | /* 38 | Epsilon:Double = 4.9406564584124654418e-324; 39 | MaxValue:Double = 1.7976931348623157081e+308; 40 | MinValue:Double = -1.7976931348623157081e+308; 41 | PositiveInfinity:Double = 1.0 / 0.0; 42 | NegativeInfinity:Double = -1.0 / 0.0; 43 | NaN:Double = 0.0 / 0.0; 44 | */ 45 | 46 | t.Log("testFloat64_MaxValue:", testFloat64_MaxValue()) 47 | t.Log("testFloat64_MinValue:", testFloat64_MinValue()) 48 | t.Log("testFloat64_Epsilon:", testFloat64_Epsilon()) 49 | 50 | } 51 | 52 | func testFloat32_MaxValue() float32 { 53 | _testFloat32_MaxValue.Call() 54 | return Getfloat32() 55 | } 56 | 57 | func testFloat32_MinValue() float32 { 58 | _testFloat32_MinValue.Call() 59 | return Getfloat32() 60 | } 61 | 62 | func testFloat32_Epsilon() float32 { 63 | _testFloat32_Epsilon.Call() 64 | return Getfloat32() 65 | } 66 | 67 | //-- float64 68 | func testFloat64_MaxValue() float64 { 69 | _testFloat64_MaxValue.Call() 70 | return Getfloat64() 71 | } 72 | 73 | func testFloat64_MinValue() float64 { 74 | _testFloat64_MinValue.Call() 75 | return Getfloat64() 76 | } 77 | 78 | func testFloat64_Epsilon() float64 { 79 | _testFloat64_Epsilon.Call() 80 | return Getfloat64() 81 | } 82 | -------------------------------------------------------------------------------- /floatpatch/asmtestdll/Project12.dpr: -------------------------------------------------------------------------------- 1 | library Project12; 2 | 3 | { Important note about DLL memory management: ShareMem must be the 4 | first unit in your library's USES clause AND your project's (select 5 | Project-View Source) USES clause if your DLL exports any procedures or 6 | functions that pass strings as parameters or function results. This 7 | applies to all strings passed to and from your DLL--even those that 8 | are nested in records and classes. ShareMem is the interface unit to 9 | the BORLNDMM.DLL shared memory manager, which must be deployed along 10 | with your DLL. To avoid using BORLNDMM.DLL, pass string information 11 | using PChar or ShortString parameters. } 12 | 13 | uses 14 | System.SysUtils, 15 | System.Classes; 16 | 17 | {$R *.res} 18 | 19 | { 20 | Epsilon:Single = 1.4012984643248170709e-45; 21 | MaxValue:Single = 340282346638528859811704183484516925440.0; 22 | MinValue:Single = -340282346638528859811704183484516925440.0; 23 | PositiveInfinity:Single = 1.0 / 0.0; 24 | NegativeInfinity:Single = -1.0 / 0.0; 25 | NaN:Single = 0.0 / 0.0; 26 | } 27 | 28 | function testFloat32_MaxValue: Single; cdecl; 29 | begin 30 | Result := Single.MaxValue; 31 | end; 32 | 33 | function testFloat32_MinValue: Single; cdecl; 34 | begin 35 | Result := Single.MinValue; 36 | end; 37 | 38 | function testFloat32_Epsilon: Single; cdecl; 39 | begin 40 | Result := Single.Epsilon; 41 | end; 42 | 43 | //function testFloat32_Value(A1, A2: Single): Single; cdecl; 44 | //begin 45 | // Result := Single.Epsilon; 46 | //end; 47 | 48 | 49 | { 50 | Epsilon:Double = 4.9406564584124654418e-324; 51 | MaxValue:Double = 1.7976931348623157081e+308; 52 | MinValue:Double = -1.7976931348623157081e+308; 53 | PositiveInfinity:Double = 1.0 / 0.0; 54 | NegativeInfinity:Double = -1.0 / 0.0; 55 | NaN:Double = 0.0 / 0.0; 56 | } 57 | 58 | function testFloat64_MaxValue: Double; cdecl; 59 | begin 60 | Result := Double.MaxValue; 61 | end; 62 | 63 | function testFloat64_MinValue: Double; cdecl; 64 | begin 65 | Result := Double.MinValue; 66 | end; 67 | 68 | function testFloat64_Epsilon: Double; cdecl; 69 | begin 70 | Result := Double.Epsilon; 71 | end; 72 | 73 | //function testFloat64_Value(A1, A2: Double): Single; cdecl; 74 | //begin 75 | // Result := Single.Epsilon; 76 | //end; 77 | 78 | 79 | 80 | 81 | exports 82 | testFloat32_MaxValue, 83 | testFloat32_MinValue, 84 | testFloat32_Epsilon, 85 | 86 | testFloat64_MaxValue, 87 | testFloat64_MinValue, 88 | testFloat64_Epsilon; 89 | 90 | begin 91 | end. 92 | -------------------------------------------------------------------------------- /floatpatch/asmtestdll/Project12.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {29BB680C-22EB-4875-8C71-E4D4B30B7BC1} 4 | 15.4 5 | None 6 | Project12.dpr 7 | True 8 | Release 9 | Win64 10 | 3 11 | Library 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Base 29 | true 30 | 31 | 32 | true 33 | Base 34 | true 35 | 36 | 37 | true 38 | Cfg_1 39 | true 40 | true 41 | 42 | 43 | true 44 | Cfg_1 45 | true 46 | true 47 | 48 | 49 | true 50 | Base 51 | true 52 | 53 | 54 | true 55 | Cfg_2 56 | true 57 | true 58 | 59 | 60 | true 61 | Cfg_2 62 | true 63 | true 64 | 65 | 66 | Project12 67 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 68 | true 69 | .\$(Platform)\$(Config) 70 | .\$(Platform)\$(Config) 71 | false 72 | false 73 | false 74 | false 75 | false 76 | 77 | 78 | DBXInterBaseDriver;DataSnapServer;DataSnapCommon;DbxCommonDriver;dbxcds;CustomIPTransport;dsnap;IndyIPServer;IndyCore;CloudService;FmxTeeUI;dsnapxml;bindcompfmx;RESTBackendComponents;dbrtl;bindcomp;inetdb;xmlrtl;ibxpress;bindengine;FMXTee;soaprtl;DBXInformixDriver;DataSnapServerMidas;DBXFirebirdDriver;inet;soapmidas;DBXSybaseASADriver;RESTComponents;dbexpress;IndyIPClient;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapProviderClient;DBXOracleDriver;fmxase;IndyIPCommon;soapserver;inetdbxpress;rtl;DbxClientDriver;DataSnapNativeClient;IndyProtocols;DBXMySQLDriver;bindcompdbx;fmxobj;fmxdae;DataSnapIndy10ServerTransport;$(DCC_UsePackage) 79 | 80 | 81 | 1033 82 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 83 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 84 | true 85 | cxSchedulerTreeBrowserRS20;CEF4Delphi;dxSkinOffice2007SilverRS20;cxGridRS20;dxPSdxLCLnkRS20;dxPScxExtCommonRS20;cxPageControlRS20;dxPSdxSpreadSheetLnkRS20;dxPSdxMapControlLnkRS20;dxSkinVisualStudio2013DarkRS20;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxSkinsdxBarPainterRS20;dxSkinSharpRS20;SynEdit_R;DbxCommonDriver;dxLayoutControlRS20;vclimg;dxSkinSilverRS20;dxSkinsdxNavBarPainterRS20;dbxcds;DatasnapConnectorsFreePascal;dxPSCoreRS20;dxSkinOffice2013LightGrayRS20;vcldb;dxPSTeeChartRS20;dxSkinOffice2013WhiteRS20;dxSkinMcSkinRS20;CustomIPTransport;DDuilibVcl;dsnap;IndyIPServer;dxSkinCoffeeRS20;dxSkinGlassOceansRS20;IndyCore;dxSkinOffice2010SilverRS20;dxComnRS20;CloudService;dxFlowChartRS20;dxSkinOffice2013DarkGrayRS20;FmxTeeUI;dxDBXServerModeRS20;cxTreeListdxBarPopupMenuRS20;dxSkinOffice2007PinkRS20;dxSkinSpringTimeRS20;dxOfficeCoreRS20;dxPsPrVwAdvRS20;dxSkiniMaginaryRS20;dxSkinVisualStudio2013BlueRS20;dxPScxGridLnkRS20;dxSkinDevExpressDarkStyleRS20;cxSchedulerGridRS20;dxtrmdRS20;dsnapxml;dxSpreadSheetRS20;dxSkinMoneyTwinsRS20;dxSkinOffice2007GreenRS20;dxPScxTLLnkRS20;dxRichEditControlRS20;cxPivotGridOLAPRS20;dxPSdxFCLnkRS20;dxPSdxGaugeControlLnkRS20;bindcompfmx;dxPDFViewerRS20;vcldbx;dxSpreadSheetConditionalFormattingDialogsRS20;RESTBackendComponents;dbrtl;bindcomp;inetdb;dxSkinVisualStudio2013LightRS20;DBXOdbcDriver;xmlrtl;ibxpress;dxSkinOffice2007BlackRS20;bindengine;vclactnband;FMXTee;soaprtl;dxGDIPlusRS20;bindcompvcl;vclie;dxPSRichEditControlLnkRS20;cxVerticalGridRS20;dxRibbonCustomizationFormRS20;cxSchedulerRS20;dxSkinBlackRS20;DBXInformixDriver;dxSkinSummer2008RS20;Intraweb;DataSnapServerMidas;DScintillaRuntime;DBXFirebirdDriver;dsnapcon;inet;dxBarRS20;cxDataRS20;dxSkinDarkSideRS20;dxPScxVGridLnkRS20;soapmidas;vclx;dxSkinLondonLiquidSkyRS20;dxCoreRS20;DBXSybaseASADriver;RESTComponents;dxPSPrVwRibbonRS20;dbexpress;dxPSLnksRS20;IndyIPClient;dxSpellCheckerRS20;dxBarExtItemsRS20;dxdbtrRS20;cxSchedulerRibbonStyleEventEditorRS20;DBXSqliteDriver;fmx;dxSkinVS2010RS20;dxPScxPCProdRS20;IndySystem;dxSkinXmas2008BlueRS20;TeeDB;tethering;vclib;inetdbbde;DataSnapClient;dxTabbedMDIRS20;dxmdsRS20;DataSnapProviderClient;DBXSybaseASEDriver;dxdborRS20;dxPSdxDBTVLnkRS20;MetropolisUILiveTile;dxSkinCaramelRS20;dxPScxSchedulerLnkRS20;dxSkinLiquidSkyRS20;dxSkinOffice2016DarkRS20;vcldsnap;dxGaugeControlRS20;dxSkinDevExpressStyleRS20;cxPivotGridChartRS20;DBXDb2Driver;DBXOracleDriver;dxSkinOffice2010BlueRS20;vclribbon;cxExportRS20;dxServerModeRS20;dxSkinscxSchedulerPainterRS20;dxSkinMetropolisDarkRS20;fmxase;vcl;DBXMSSQLDriver;IndyIPCommon;dxSkinBlueRS20;dxSkinsdxDLPainterRS20;dxBarExtDBItemsRS20;dxSkinOffice2010BlackRS20;soapserver;dxPSDBTeeChartRS20;dxHttpIndyRequestRS20;inetdbxpress;dxADOServerModeRS20;dxSkinBlueprintRS20;dxSkinFoggyRS20;dxSkinSharpPlusRS20;cxPivotGridRS20;adortl;dxSkinOffice2016ColorfulRS20;dxRibbonRS20;dxSkinHighContrastRS20;dxSkinTheAsphaltWorldRS20;dxBarDBNavRS20;dxSkinscxPCPainterRS20;YzzVclComponent;rtl;DbxClientDriver;dxSkinMetropolisRS20;dxNavBarRS20;dxDockingRS20;Tee;dxSkinOffice2007BlueRS20;dxSkinsdxRibbonPainterRS20;dxSkinValentineRS20;DataSnapNativeClient;svnui;IndyProtocols;DBXMySQLDriver;dxPScxCommonRS20;dxSkinSevenClassicRS20;dxSkinPumpkinRS20;bindcompdbx;TeeUI;dxSkinDarkRoomRS20;vcltouch;dxSkinStardustRS20;cxEditorsRS20;dxorgcRS20;dxPSdxDBOCLnkRS20;VCLRESTComponents;VclSmp;dxSkinsCoreRS20;DataSnapConnectors;dxSkinSevenRS20;cxLibraryRS20;fmxobj;dxMapControlRS20;svn;dxWizardControlRS20;dxSkinLilianRS20;fmxdae;dxSkinWhiteprintRS20;dxPScxPivotGridLnkRS20;bdertl;dxThemeRS20;dxPSdxOCLnkRS20;dxTileControlRS20;DataSnapIndy10ServerTransport;cxTreeListRS20;$(DCC_UsePackage) 86 | 87 | 88 | 1033 89 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) 90 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 91 | true 92 | cxSchedulerTreeBrowserRS20;dxSkinOffice2007SilverRS20;cxGridRS20;dxPSdxLCLnkRS20;dxPScxExtCommonRS20;cxPageControlRS20;dxPSdxSpreadSheetLnkRS20;dxPSdxMapControlLnkRS20;dxSkinVisualStudio2013DarkRS20;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxSkinsdxBarPainterRS20;dxSkinSharpRS20;DbxCommonDriver;dxLayoutControlRS20;vclimg;dxSkinSilverRS20;dxSkinsdxNavBarPainterRS20;dbxcds;DatasnapConnectorsFreePascal;dxPSCoreRS20;dxSkinOffice2013LightGrayRS20;vcldb;dxPSTeeChartRS20;dxSkinOffice2013WhiteRS20;dxSkinMcSkinRS20;CustomIPTransport;dsnap;IndyIPServer;dxSkinCoffeeRS20;dxSkinGlassOceansRS20;IndyCore;dxSkinOffice2010SilverRS20;dxComnRS20;CloudService;dxFlowChartRS20;dxSkinOffice2013DarkGrayRS20;FmxTeeUI;dxDBXServerModeRS20;cxTreeListdxBarPopupMenuRS20;dxSkinOffice2007PinkRS20;dxSkinSpringTimeRS20;dxOfficeCoreRS20;dxPsPrVwAdvRS20;dxSkiniMaginaryRS20;dxSkinVisualStudio2013BlueRS20;dxPScxGridLnkRS20;dxSkinDevExpressDarkStyleRS20;cxSchedulerGridRS20;dxtrmdRS20;dsnapxml;dxSpreadSheetRS20;dxSkinMoneyTwinsRS20;dxSkinOffice2007GreenRS20;dxPScxTLLnkRS20;dxRichEditControlRS20;cxPivotGridOLAPRS20;dxPSdxFCLnkRS20;dxPSdxGaugeControlLnkRS20;bindcompfmx;dxPDFViewerRS20;dxSpreadSheetConditionalFormattingDialogsRS20;RESTBackendComponents;dbrtl;bindcomp;inetdb;dxSkinVisualStudio2013LightRS20;DBXOdbcDriver;xmlrtl;ibxpress;dxSkinOffice2007BlackRS20;bindengine;vclactnband;FMXTee;soaprtl;dxGDIPlusRS20;bindcompvcl;vclie;dxPSRichEditControlLnkRS20;cxVerticalGridRS20;dxRibbonCustomizationFormRS20;cxSchedulerRS20;dxSkinBlackRS20;DBXInformixDriver;dxSkinSummer2008RS20;Intraweb;DataSnapServerMidas;DScintillaRuntime;DBXFirebirdDriver;dsnapcon;inet;dxBarRS20;cxDataRS20;dxSkinDarkSideRS20;dxPScxVGridLnkRS20;soapmidas;vclx;dxSkinLondonLiquidSkyRS20;dxCoreRS20;DBXSybaseASADriver;RESTComponents;dxPSPrVwRibbonRS20;dbexpress;dxPSLnksRS20;IndyIPClient;dxSpellCheckerRS20;dxBarExtItemsRS20;dxdbtrRS20;cxSchedulerRibbonStyleEventEditorRS20;DBXSqliteDriver;fmx;dxSkinVS2010RS20;dxPScxPCProdRS20;IndySystem;dxSkinXmas2008BlueRS20;TeeDB;tethering;vclib;DataSnapClient;dxTabbedMDIRS20;dxmdsRS20;DataSnapProviderClient;DBXSybaseASEDriver;dxdborRS20;dxPSdxDBTVLnkRS20;MetropolisUILiveTile;dxSkinCaramelRS20;dxPScxSchedulerLnkRS20;dxSkinLiquidSkyRS20;dxSkinOffice2016DarkRS20;vcldsnap;dxGaugeControlRS20;dxSkinDevExpressStyleRS20;cxPivotGridChartRS20;DBXDb2Driver;DBXOracleDriver;dxSkinOffice2010BlueRS20;vclribbon;cxExportRS20;dxServerModeRS20;dxSkinscxSchedulerPainterRS20;dxSkinMetropolisDarkRS20;fmxase;vcl;DBXMSSQLDriver;IndyIPCommon;dxSkinBlueRS20;dxSkinsdxDLPainterRS20;dxBarExtDBItemsRS20;dxSkinOffice2010BlackRS20;soapserver;dxPSDBTeeChartRS20;dxHttpIndyRequestRS20;inetdbxpress;dxADOServerModeRS20;dxSkinBlueprintRS20;dxSkinFoggyRS20;dxSkinSharpPlusRS20;cxPivotGridRS20;adortl;dxSkinOffice2016ColorfulRS20;dxRibbonRS20;dxSkinHighContrastRS20;dxSkinTheAsphaltWorldRS20;dxBarDBNavRS20;dxSkinscxPCPainterRS20;rtl;DbxClientDriver;dxSkinMetropolisRS20;dxNavBarRS20;dxDockingRS20;Tee;dxSkinOffice2007BlueRS20;dxSkinsdxRibbonPainterRS20;dxSkinValentineRS20;DataSnapNativeClient;IndyProtocols;DBXMySQLDriver;dxPScxCommonRS20;dxSkinSevenClassicRS20;dxSkinPumpkinRS20;bindcompdbx;TeeUI;dxSkinDarkRoomRS20;vcltouch;dxSkinStardustRS20;cxEditorsRS20;dxorgcRS20;dxPSdxDBOCLnkRS20;VCLRESTComponents;VclSmp;dxSkinsCoreRS20;DataSnapConnectors;dxSkinSevenRS20;cxLibraryRS20;fmxobj;dxMapControlRS20;dxWizardControlRS20;dxSkinLilianRS20;fmxdae;dxSkinWhiteprintRS20;dxPScxPivotGridLnkRS20;dxThemeRS20;dxPSdxOCLnkRS20;dxTileControlRS20;DataSnapIndy10ServerTransport;cxTreeListRS20;$(DCC_UsePackage) 93 | 94 | 95 | DEBUG;$(DCC_Define) 96 | true 97 | false 98 | true 99 | true 100 | true 101 | 102 | 103 | .\ 104 | F:\Golang\src\asmTest\asmTest.exe 105 | 1033 106 | true 107 | None 108 | false 109 | 110 | 111 | 1033 112 | .\ 113 | true 114 | None 115 | 116 | 117 | false 118 | RELEASE;$(DCC_Define) 119 | 0 120 | 0 121 | 122 | 123 | 1033 124 | None 125 | true 126 | .\ 127 | 128 | 129 | 1033 130 | None 131 | true 132 | .\ 133 | 134 | 135 | 136 | MainSource 137 | 138 | 139 | Cfg_2 140 | Base 141 | 142 | 143 | Base 144 | 145 | 146 | Cfg_1 147 | Base 148 | 149 | 150 | 151 | Delphi.Personality.12 152 | 153 | 154 | 155 | 156 | Project12.dpr 157 | 158 | 159 | Microsoft Office 2000 Sample Automation Server Wrapper Components 160 | Microsoft Office XP Sample Automation Server Wrapper Components 161 | 162 | 163 | 164 | 165 | False 166 | True 167 | True 168 | 169 | 170 | 12 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /floatpatch/floatResultPatch.go: -------------------------------------------------------------------------------- 1 | // +build !arm 2 | 3 | /* 4 | 用于解决syscall不能返回浮点的补丁,用法参考REAMDME.md 5 | 6 | */ 7 | 8 | package floatpatch 9 | 10 | func Getfloat32() float32 11 | 12 | func Getfloat64() float64 13 | -------------------------------------------------------------------------------- /floatpatch/floatResultPatch_386.s: -------------------------------------------------------------------------------- 1 | #include "textflag.h" 2 | 3 | // 一个补丁 by:ying32 4 | // 由于go的syscall不能返回浮点数,所以直接用汇编获取浮点寄存器F0的值,并返回。 5 | 6 | // float32 Getfloat32(); 7 | TEXT ·Getfloat32(SB),NOSPLIT|NOFRAME,$0 8 | FMOVFP F0, ret(FP) 9 | RET 10 | 11 | // float64 Getfloat64(); 12 | TEXT ·Getfloat64(SB),NOSPLIT|NOFRAME,$0 13 | FMOVDP F0, ret(FP) 14 | RET 15 | -------------------------------------------------------------------------------- /floatpatch/floatResultPatch_amd64.s: -------------------------------------------------------------------------------- 1 | #include "textflag.h" 2 | 3 | // 一个补丁 by:ying32 4 | // 由于go的syscall不能返回浮点数,所以直接用汇编获取浮点寄存器xmm0的值,并返回。 5 | 6 | // float32 Getfloat32(); 7 | TEXT ·Getfloat32(SB),NOSPLIT|NOFRAME,$0 8 | MOVL X0, ret(FP) 9 | RET 10 | 11 | // float64 Getfloat64(); 12 | TEXT ·Getfloat64(SB),NOSPLIT|NOFRAME,$0 13 | MOVQ X0, ret(FP) 14 | RET 15 | -------------------------------------------------------------------------------- /testdll/testdll.dpr: -------------------------------------------------------------------------------- 1 | library testdll; 2 | 3 | { Important note about DLL memory management: ShareMem must be the 4 | first unit in your library's USES clause AND your project's (select 5 | Project-View Source) USES clause if your DLL exports any procedures or 6 | functions that pass strings as parameters or function results. This 7 | applies to all strings passed to and from your DLL--even those that 8 | are nested in records and classes. ShareMem is the interface unit to 9 | the BORLNDMM.DLL shared memory manager, which must be deployed along 10 | with your DLL. To avoid using BORLNDMM.DLL, pass string information 11 | using PChar or ShortString parameters. } 12 | 13 | uses 14 | System.SysUtils, 15 | System.Classes; 16 | 17 | {$R *.res} 18 | 19 | 20 | 21 | // dylib 22 | type 23 | TSyscall0 = function: UInt64; stdcall; 24 | TSyscall1 = function(A1: Pointer): UInt64; stdcall; 25 | TSyscall2 = function(A1, A2: Pointer): UInt64; stdcall; 26 | TSyscall3 = function(A1, A2, A3: Pointer): UInt64; stdcall; 27 | TSyscall4 = function(A1, A2, A3, A4: Pointer): UInt64; stdcall; 28 | TSyscall5 = function(A1, A2, A3, A4, A5: Pointer): UInt64; stdcall; 29 | TSyscall6 = function(A1, A2, A3, A4, A5, A6: Pointer): UInt64; stdcall; 30 | TSyscall7 = function(A1, A2, A3, A4, A5, A6, A7: Pointer): UInt64; stdcall; 31 | TSyscall8 = function(A1, A2, A3, A4, A5, A6, A7, A8: Pointer): UInt64; stdcall; 32 | TSyscall9 = function(A1, A2, A3, A4, A5, A6, A7, A8, A9: Pointer): UInt64; stdcall; 33 | TSyscall10 = function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10: Pointer): UInt64; stdcall; 34 | TSyscall11 = function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11: Pointer): UInt64; stdcall; 35 | TSyscall12 = function(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: Pointer): UInt64; stdcall; 36 | 37 | function MySyscall(AProc: Pointer; ALen: NativeInt; A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: Pointer): UInt64; stdcall; 38 | begin 39 | Result := 0; 40 | if AProc = nil then 41 | Exit; 42 | try 43 | case ALen of 44 | 0: Result := TSyscall0(AProc)(); 45 | 1: Result := TSyscall1(AProc)(A1); 46 | 2: Result := TSyscall2(AProc)(A1, A2); 47 | 3: Result := TSyscall3(AProc)(A1, A2, A3); 48 | 4: Result := TSyscall4(AProc)(A1, A2, A3, A4); 49 | 5: Result := TSyscall5(AProc)(A1, A2, A3, A4, A5); 50 | 6: Result := TSyscall6(AProc)(A1, A2, A3, A4, A5, A6); 51 | 7: Result := TSyscall7(AProc)(A1, A2, A3, A4, A5, A6, A7); 52 | 8: Result := TSyscall8(AProc)(A1, A2, A3, A4, A5, A6, A7, A8); 53 | 9: Result := TSyscall9(AProc)(A1, A2, A3, A4, A5, A6, A7, A8, A9); 54 | 10: Result := TSyscall10(AProc)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); 55 | 11: Result := TSyscall11(AProc)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11); 56 | 12: Result := TSyscall12(AProc)(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12); 57 | else 58 | Exit; 59 | end; 60 | except 61 | on E: Exception do 62 | begin 63 | Writeln('Syscall', ALen, ' Error: ', E.Message); 64 | end; 65 | end; 66 | end; 67 | 68 | 69 | function ResultValue: Int64; stdcall; 70 | begin 71 | Result := Int64.MaxValue; 72 | end; 73 | 74 | function ResultValAndParam(p1, p2: Int64): UInt64; stdcall; 75 | begin 76 | Writeln('p1:', p1, ', p2:', p2); 77 | if p1 = $FF2233445500 then 78 | Writeln('---p1 ok.') 79 | else 80 | Writeln('---p1 fail.'); 81 | 82 | if p2 = $FF6677889900 then 83 | Writeln('---p2 ok.') 84 | else 85 | Writeln('---p2 fail.'); 86 | 87 | Result := UInt64.MaxValue; 88 | end; 89 | 90 | 91 | function ResultValue32: Integer; stdcall; 92 | begin 93 | Result := Integer.MaxValue; 94 | end; 95 | 96 | function ResultValAndParam32(p1, p2: Integer): Cardinal; stdcall; 97 | begin 98 | Writeln('p1:', p1, ', p2:', p2); 99 | if p1 = $0F112233 then 100 | Writeln('---p1 ok.') 101 | else 102 | Writeln('---p1 fail.'); 103 | 104 | if p2 = $0F445566 then 105 | Writeln('---p2 ok.') 106 | else 107 | Writeln('---p2 fail.'); 108 | 109 | Result := Cardinal.MaxValue; 110 | end; 111 | 112 | exports 113 | ResultValue, 114 | ResultValAndParam, 115 | 116 | ResultValue32, 117 | ResultValAndParam32, 118 | 119 | MySyscall; 120 | 121 | begin 122 | end. 123 | 124 | -------------------------------------------------------------------------------- /testdll/testdll.dproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | {F6E9491B-C72F-4EFC-A559-29BC569DCB5F} 4 | 15.4 5 | None 6 | testdll.dpr 7 | True 8 | Release 9 | Win64 10 | 3 11 | Library 12 | 13 | 14 | true 15 | 16 | 17 | true 18 | Base 19 | true 20 | 21 | 22 | true 23 | Base 24 | true 25 | 26 | 27 | true 28 | Base 29 | true 30 | 31 | 32 | true 33 | Base 34 | true 35 | 36 | 37 | true 38 | Cfg_1 39 | true 40 | true 41 | 42 | 43 | true 44 | Cfg_1 45 | true 46 | true 47 | 48 | 49 | true 50 | Base 51 | true 52 | 53 | 54 | true 55 | Cfg_2 56 | true 57 | true 58 | 59 | 60 | 2052 61 | None 62 | CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments= 63 | testdll 64 | System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace) 65 | true 66 | .\$(Platform)\$(Config) 67 | .\$(Platform)\$(Config) 68 | false 69 | false 70 | false 71 | false 72 | false 73 | 74 | 75 | DBXInterBaseDriver;DataSnapServer;DataSnapCommon;DbxCommonDriver;dbxcds;CustomIPTransport;dsnap;IndyIPServer;IndyCore;CloudService;FmxTeeUI;dsnapxml;bindcompfmx;RESTBackendComponents;dbrtl;bindcomp;inetdb;xmlrtl;ibxpress;bindengine;FMXTee;soaprtl;DBXInformixDriver;DataSnapServerMidas;DBXFirebirdDriver;inet;soapmidas;DBXSybaseASADriver;RESTComponents;dbexpress;IndyIPClient;DBXSqliteDriver;fmx;IndySystem;tethering;DataSnapClient;DataSnapProviderClient;DBXOracleDriver;fmxase;IndyIPCommon;soapserver;inetdbxpress;rtl;DbxClientDriver;DataSnapNativeClient;IndyProtocols;DBXMySQLDriver;bindcompdbx;fmxobj;fmxdae;DataSnapIndy10ServerTransport;$(DCC_UsePackage) 76 | 77 | 78 | 80 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace) 81 | cxSchedulerTreeBrowserRS20;CEF4Delphi;dxSkinOffice2007SilverRS20;cxGridRS20;dxPSdxLCLnkRS20;dxPScxExtCommonRS20;cxPageControlRS20;dxPSdxSpreadSheetLnkRS20;dxPSdxMapControlLnkRS20;dxSkinVisualStudio2013DarkRS20;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxSkinsdxBarPainterRS20;dxSkinSharpRS20;DbxCommonDriver;dxLayoutControlRS20;vclimg;dxSkinSilverRS20;dxSkinsdxNavBarPainterRS20;dbxcds;DatasnapConnectorsFreePascal;dxPSCoreRS20;dxSkinOffice2013LightGrayRS20;vcldb;dxPSTeeChartRS20;dxSkinOffice2013WhiteRS20;dxSkinMcSkinRS20;CustomIPTransport;DDuilibVcl;dsnap;IndyIPServer;dxSkinCoffeeRS20;dxSkinGlassOceansRS20;IndyCore;dxSkinOffice2010SilverRS20;dxComnRS20;CloudService;dxFlowChartRS20;dxSkinOffice2013DarkGrayRS20;FmxTeeUI;dxDBXServerModeRS20;cxTreeListdxBarPopupMenuRS20;dxSkinOffice2007PinkRS20;dxSkinSpringTimeRS20;dxOfficeCoreRS20;dxPsPrVwAdvRS20;dxSkiniMaginaryRS20;dxSkinVisualStudio2013BlueRS20;dxPScxGridLnkRS20;dxSkinDevExpressDarkStyleRS20;cxSchedulerGridRS20;dxtrmdRS20;dsnapxml;dxSpreadSheetRS20;dxSkinMoneyTwinsRS20;dxSkinOffice2007GreenRS20;dxPScxTLLnkRS20;dxRichEditControlRS20;cxPivotGridOLAPRS20;dxPSdxFCLnkRS20;dxPSdxGaugeControlLnkRS20;bindcompfmx;dxPDFViewerRS20;vcldbx;dxSpreadSheetConditionalFormattingDialogsRS20;RESTBackendComponents;dbrtl;bindcomp;inetdb;dxSkinVisualStudio2013LightRS20;DBXOdbcDriver;xmlrtl;ibxpress;dxSkinOffice2007BlackRS20;bindengine;vclactnband;FMXTee;soaprtl;dxGDIPlusRS20;bindcompvcl;vclie;dxPSRichEditControlLnkRS20;cxVerticalGridRS20;dxRibbonCustomizationFormRS20;cxSchedulerRS20;dxSkinBlackRS20;DBXInformixDriver;dxSkinSummer2008RS20;Intraweb;DataSnapServerMidas;DBXFirebirdDriver;dsnapcon;inet;dxBarRS20;cxDataRS20;dxSkinDarkSideRS20;dxPScxVGridLnkRS20;soapmidas;vclx;dxSkinLondonLiquidSkyRS20;dxCoreRS20;DBXSybaseASADriver;RESTComponents;dxPSPrVwRibbonRS20;dbexpress;dxPSLnksRS20;IndyIPClient;dxSpellCheckerRS20;dxBarExtItemsRS20;dxdbtrRS20;cxSchedulerRibbonStyleEventEditorRS20;DBXSqliteDriver;fmx;dxSkinVS2010RS20;dxPScxPCProdRS20;IndySystem;dxSkinXmas2008BlueRS20;TeeDB;tethering;vclib;inetdbbde;DataSnapClient;dxTabbedMDIRS20;dxmdsRS20;DataSnapProviderClient;DBXSybaseASEDriver;dxdborRS20;dxPSdxDBTVLnkRS20;MetropolisUILiveTile;dxSkinCaramelRS20;dxPScxSchedulerLnkRS20;dxSkinLiquidSkyRS20;dxSkinOffice2016DarkRS20;vcldsnap;dxGaugeControlRS20;dxSkinDevExpressStyleRS20;cxPivotGridChartRS20;DBXDb2Driver;DBXOracleDriver;dxSkinOffice2010BlueRS20;vclribbon;cxExportRS20;dxServerModeRS20;dxSkinscxSchedulerPainterRS20;dxSkinMetropolisDarkRS20;fmxase;vcl;DBXMSSQLDriver;IndyIPCommon;dxSkinBlueRS20;dxSkinsdxDLPainterRS20;dxBarExtDBItemsRS20;dxSkinOffice2010BlackRS20;soapserver;dxPSDBTeeChartRS20;dxHttpIndyRequestRS20;inetdbxpress;dxADOServerModeRS20;dxSkinBlueprintRS20;dxSkinFoggyRS20;dxSkinSharpPlusRS20;cxPivotGridRS20;adortl;dxSkinOffice2016ColorfulRS20;dxRibbonRS20;dxSkinHighContrastRS20;dxSkinTheAsphaltWorldRS20;dxBarDBNavRS20;dxSkinscxPCPainterRS20;rtl;DbxClientDriver;dxSkinMetropolisRS20;dxNavBarRS20;dxDockingRS20;Tee;dxSkinOffice2007BlueRS20;dxSkinsdxRibbonPainterRS20;dxSkinValentineRS20;DataSnapNativeClient;svnui;IndyProtocols;DBXMySQLDriver;dxPScxCommonRS20;dxSkinSevenClassicRS20;dxSkinPumpkinRS20;bindcompdbx;TeeUI;dxSkinDarkRoomRS20;vcltouch;dxSkinStardustRS20;cxEditorsRS20;dxorgcRS20;dxPSdxDBOCLnkRS20;VCLRESTComponents;VclSmp;dxSkinsCoreRS20;DataSnapConnectors;dxSkinSevenRS20;cxLibraryRS20;fmxobj;dxMapControlRS20;svn;dxWizardControlRS20;dxSkinLilianRS20;fmxdae;dxSkinWhiteprintRS20;dxPScxPivotGridLnkRS20;bdertl;dxThemeRS20;dxPSdxOCLnkRS20;dxTileControlRS20;DataSnapIndy10ServerTransport;cxTreeListRS20;$(DCC_UsePackage) 82 | true 83 | 1033 84 | ..\ 85 | 86 | 87 | 89 | Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace) 90 | cxSchedulerTreeBrowserRS20;dxSkinOffice2007SilverRS20;cxGridRS20;dxPSdxLCLnkRS20;dxPScxExtCommonRS20;cxPageControlRS20;dxPSdxSpreadSheetLnkRS20;dxPSdxMapControlLnkRS20;dxSkinVisualStudio2013DarkRS20;DBXInterBaseDriver;DataSnapServer;DataSnapCommon;dxSkinsdxBarPainterRS20;dxSkinSharpRS20;DbxCommonDriver;dxLayoutControlRS20;vclimg;dxSkinSilverRS20;dxSkinsdxNavBarPainterRS20;dbxcds;DatasnapConnectorsFreePascal;dxPSCoreRS20;dxSkinOffice2013LightGrayRS20;vcldb;dxPSTeeChartRS20;dxSkinOffice2013WhiteRS20;dxSkinMcSkinRS20;CustomIPTransport;dsnap;IndyIPServer;dxSkinCoffeeRS20;dxSkinGlassOceansRS20;IndyCore;dxSkinOffice2010SilverRS20;dxComnRS20;CloudService;dxFlowChartRS20;dxSkinOffice2013DarkGrayRS20;FmxTeeUI;dxDBXServerModeRS20;cxTreeListdxBarPopupMenuRS20;dxSkinOffice2007PinkRS20;dxSkinSpringTimeRS20;dxOfficeCoreRS20;dxPsPrVwAdvRS20;dxSkiniMaginaryRS20;dxSkinVisualStudio2013BlueRS20;dxPScxGridLnkRS20;dxSkinDevExpressDarkStyleRS20;cxSchedulerGridRS20;dxtrmdRS20;dsnapxml;dxSpreadSheetRS20;dxSkinMoneyTwinsRS20;dxSkinOffice2007GreenRS20;dxPScxTLLnkRS20;dxRichEditControlRS20;cxPivotGridOLAPRS20;dxPSdxFCLnkRS20;dxPSdxGaugeControlLnkRS20;bindcompfmx;dxPDFViewerRS20;dxSpreadSheetConditionalFormattingDialogsRS20;RESTBackendComponents;dbrtl;bindcomp;inetdb;dxSkinVisualStudio2013LightRS20;DBXOdbcDriver;xmlrtl;ibxpress;dxSkinOffice2007BlackRS20;bindengine;vclactnband;FMXTee;soaprtl;dxGDIPlusRS20;bindcompvcl;vclie;dxPSRichEditControlLnkRS20;cxVerticalGridRS20;dxRibbonCustomizationFormRS20;cxSchedulerRS20;dxSkinBlackRS20;DBXInformixDriver;dxSkinSummer2008RS20;Intraweb;DataSnapServerMidas;DBXFirebirdDriver;dsnapcon;inet;dxBarRS20;cxDataRS20;dxSkinDarkSideRS20;dxPScxVGridLnkRS20;soapmidas;vclx;dxSkinLondonLiquidSkyRS20;dxCoreRS20;DBXSybaseASADriver;RESTComponents;dxPSPrVwRibbonRS20;dbexpress;dxPSLnksRS20;IndyIPClient;dxSpellCheckerRS20;dxBarExtItemsRS20;dxdbtrRS20;cxSchedulerRibbonStyleEventEditorRS20;DBXSqliteDriver;fmx;dxSkinVS2010RS20;dxPScxPCProdRS20;IndySystem;dxSkinXmas2008BlueRS20;TeeDB;tethering;vclib;DataSnapClient;dxTabbedMDIRS20;dxmdsRS20;DataSnapProviderClient;DBXSybaseASEDriver;dxdborRS20;dxPSdxDBTVLnkRS20;MetropolisUILiveTile;dxSkinCaramelRS20;dxPScxSchedulerLnkRS20;dxSkinLiquidSkyRS20;dxSkinOffice2016DarkRS20;vcldsnap;dxGaugeControlRS20;dxSkinDevExpressStyleRS20;cxPivotGridChartRS20;DBXDb2Driver;DBXOracleDriver;dxSkinOffice2010BlueRS20;vclribbon;cxExportRS20;dxServerModeRS20;dxSkinscxSchedulerPainterRS20;dxSkinMetropolisDarkRS20;fmxase;vcl;DBXMSSQLDriver;IndyIPCommon;dxSkinBlueRS20;dxSkinsdxDLPainterRS20;dxBarExtDBItemsRS20;dxSkinOffice2010BlackRS20;soapserver;dxPSDBTeeChartRS20;dxHttpIndyRequestRS20;inetdbxpress;dxADOServerModeRS20;dxSkinBlueprintRS20;dxSkinFoggyRS20;dxSkinSharpPlusRS20;cxPivotGridRS20;adortl;dxSkinOffice2016ColorfulRS20;dxRibbonRS20;dxSkinHighContrastRS20;dxSkinTheAsphaltWorldRS20;dxBarDBNavRS20;dxSkinscxPCPainterRS20;rtl;DbxClientDriver;dxSkinMetropolisRS20;dxNavBarRS20;dxDockingRS20;Tee;dxSkinOffice2007BlueRS20;dxSkinsdxRibbonPainterRS20;dxSkinValentineRS20;DataSnapNativeClient;IndyProtocols;DBXMySQLDriver;dxPScxCommonRS20;dxSkinSevenClassicRS20;dxSkinPumpkinRS20;bindcompdbx;TeeUI;dxSkinDarkRoomRS20;vcltouch;dxSkinStardustRS20;cxEditorsRS20;dxorgcRS20;dxPSdxDBOCLnkRS20;VCLRESTComponents;VclSmp;dxSkinsCoreRS20;DataSnapConnectors;dxSkinSevenRS20;cxLibraryRS20;fmxobj;dxMapControlRS20;dxWizardControlRS20;dxSkinLilianRS20;fmxdae;dxSkinWhiteprintRS20;dxPScxPivotGridLnkRS20;dxThemeRS20;dxPSdxOCLnkRS20;dxTileControlRS20;DataSnapIndy10ServerTransport;cxTreeListRS20;$(DCC_UsePackage) 91 | true 92 | 1033 93 | ..\ 94 | 95 | 96 | DEBUG;$(DCC_Define) 97 | true 98 | false 99 | true 100 | true 101 | true 102 | 103 | 104 | false 105 | 106 | 107 | true 108 | 1033 109 | None 110 | 111 | 112 | false 113 | RELEASE;$(DCC_Define) 114 | 0 115 | 0 116 | 117 | 118 | true 119 | 1033 120 | 121 | 122 | 123 | MainSource 124 | 125 | 126 | Cfg_2 127 | Base 128 | 129 | 130 | Base 131 | 132 | 133 | Cfg_1 134 | Base 135 | 136 | 137 | 138 | Delphi.Personality.12 139 | 140 | 141 | 142 | 143 | testdll.dpr 144 | 145 | 146 | Microsoft Office 2000 Sample Automation Server Wrapper Components 147 | Microsoft Office XP Sample Automation Server Wrapper Components 148 | 149 | 150 | 151 | 152 | False 153 | True 154 | True 155 | 156 | 157 | 12 158 | 159 | 160 | 161 | 162 | 163 | False 164 | 165 | False 166 | Move "$(OUTPUTDIR)testdll.dll" "$(OUTPUTDIR)testdll_386.dll" 167 | False 168 | 169 | 170 | 171 | False 172 | 173 | False 174 | Move "$(OUTPUTDIR)testdll.dll" "$(OUTPUTDIR)testdll_amd64.dll" 175 | False 176 | 177 | 178 | 179 | False 180 | 181 | False 182 | Move "$(OUTPUTDIR)testdll.dll" "$(OUTPUTDIR)testdll_386.dll" 183 | False 184 | 185 | 186 | 187 | False 188 | 189 | False 190 | Move "$(OUTPUTDIR)testdll.dll" "$(OUTPUTDIR)testdll_amd64.dll" 191 | False 192 | 193 | 194 | --------------------------------------------------------------------------------