__declspec(dllexport) void __cdecl memcopy(void *pDst, const void *pSrc, unsigned int nSize) { __asm {
mov esi, pSrc
mov edi, pDst
mov ecx, nSize $L1:
movq mm7, [esi]
add esi, 8
movq [edi], mm7
add edi, 8
dec ecx
jne $L1 }; }
这是CopyBlit8x8.dll的代码
我成功将此.dll导入C ++控制台应用程序,并将字符串'Hello World'从char * a复制到char * b。然后回声b成功地展示了'Hello World'。
然后,由于这是一个通用的内存复制例程,它接受两个指针来执行复制,我在下面做了这个;
图片基本上讲的是帖子标题〜坏图像格式例外。错误代码:0x8007000B。
这是一个通用错误,信息很少,因为它适用于各种场景。但是,我可以放心地假设它与指针有关。
我想要的是一个快速ASM模块来执行通用内存副本,但是对于vb.NET图像。
任何提示,Stack Overflow!
答案 0 :(得分:1)
当您尝试加载以与应用程序不同的位数编译的程序集或dll时,抛出BadImageFormatException。例如,如果您尝试在64位应用程序中加载32位dll(反之亦然)。
确保以与应用程序相同的位数编译dll。如果应用程序编译为AnyCPU
,则强制它为x86
或x64
, 或 使用每个位编译两个dll ,然后导入每个函数(但名称不同),并在检查Environment.Is64BitProcess
property后调用正确的函数。
这是AnyCPU
解决方案的一个示例:
'32-bit dll
<DllImport("CopyBlit8x8.dll")> _
Public Shared Function memcopy(<insert parameters here>)
End Function
'64-bit dll
<DllImport("CopyBlit8x8_x64.dll")> _
Public Shared Function memcopy64(<insert parameters here>)
End Function
Public Sub DoStuff()
If Environment.Is64BitProcess = True Then
memcopy64(...) 'Call 64-bit dll
Else
memcopy(...) 'Call 32-bit dll
End If
End Sub
修改强>
根据Hans Passant的说法,ASM MMX指令不能在x64中使用,因此我的上述解决方案对您不起作用。但是我将它留在那里因为它适用于使用本机C / C ++代码编译的DLL。
答案 1 :(得分:0)
代码:全选
__declspec(dllexport) int __cdecl testApp(long *dst, long *src)
{
__asm {
mov eax, src
mov dst, eax
};
return *dst;
}
以上代码是工作副本操作。
代码:全选
Option Explicit On
Imports System.Runtime.InteropServices
Imports System.Text
Imports wow64
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim bm As New Bitmap("1.png")
Dim bm2 As New Bitmap(640, 400)
Dim sb As New StringBuilder
sb.Append("Helo World.")
Dim src() As Byte = ASCIIEncoding.ASCII.GetBytes("Hello")
Dim dst() As Byte = ASCIIEncoding.ASCII.GetBytes("World")
Dim a As IntPtr = Marshal.AllocHGlobal(10)
Dim o As IntPtr = Marshal.AllocHGlobal(10)
Dim i() As Integer = {2, 1}
Marshal.Copy(i, 0, o, 2)
a = (wow64.movq.testApp(a, o))
Button1.Text = ASCIIEncoding.ASCII.GetChars(src)
TextBox1.Text = Marshal.ReadIntPtr(a, 4).ToString
Marshal.FreeHGlobal(a)
'Marshal.FreeHGlobal(o)
End Sub
End Class
Namespace wow64
Public Class movq
<DllImport("D:\CopyBlit8x8.dll", CallingConvention:=CallingConvention.Cdecl)> Public Shared Sub memcopy(ByRef pDsc As StringBuilder, ByRef pSrc As StringBuilder, ByVal nSize As Integer)
End Sub
<DllImport("D:\CopyBlit8x8.dll", CallingConvention:=CallingConvention.Cdecl)> Public Shared Function myPuts(ByRef str As StringBuilder) As Integer
End Function
<DllImport("D:\CopyBlit8x8.dll", CallingConvention:=CallingConvention.Cdecl)> Public Shared Function testApp(ByRef i As Long, ByRef p As Long) As Integer
End Function
End Class
End Namespace
此代码是在VB.NET中实现的复制操作。
代码:全选
TextBox1.Text = Marshal.ReadIntPtr(a, 4).ToString
这个编组例程使用4 ^增量来读取数组。
简单,嗯?