__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 }; }
This is the Code from CopyBlit8x8.dll
I successfully imported this .dll into a C++ Console Application and copied a string 'Hello World' from char * a, to char * b. Then echoed b succesfully showing 'Hello World'.
Then, as this is a generic memory copy routine that accepts two pointers to perform the copy, I did this below;
The picture basically said about the post title ~ Bad Image Format Exception. Err Code: 0x8007000B.
This is a generic error with little information as it applies to variety of scenarios. But, I can safely assume, its something to do with pointers.
What I want is a fast ASM module to perform generic memory copies,but for vb.NET images.
Any tips, Stack Overflow!
A BadImageFormatException is thrown when you try to load an assembly or dll that is compiled under a different bitness than the application. For instance if you try to load a 32-bit dll in a 64-bit application (or vice versa).
Make sure that the dll is compiled in the same bitness as the application. If the application is compiled as AnyCPU
then either force it to be x86
or x64
, or compile two dlls using each bitness, then import each function (but with different names) and call the correct one after checking the Environment.Is64BitProcess
property.
This is an example of the AnyCPU
solution:
'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
EDIT:
According to Hans Passant, ASM MMX instructions can't be used in x64, so my solution above would not work for you. However I'm leaving it there because it works for DLLs compiled using native C/C++ code.
Code: Select all
__declspec(dllexport) int __cdecl testApp(long *dst, long *src)
{
__asm {
mov eax, src
mov dst, eax
};
return *dst;
}
This code above is the working copy operation.
Code: Select all
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
This code is the copy operation implemented in VB.NET.
Code: Select all
TextBox1.Text = Marshal.ReadIntPtr(a, 4).ToString
This marshal routine uses 4^increments to read through the array.
Simple, eh?
User contributions licensed under CC BY-SA 3.0