2016-11-13 40 views
0
__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.dllVB.NET錯誤:0x8007000B(壞圖像格式除外)

我成功導入這個.dll成C++控制檯應用程序和複製一個字符串的「Hello World」這是代碼char * a,char * b。然後迴應b成功地顯示'Hello World'。

然後,因爲這是一個通用的內存拷貝例程,它接受兩個指針來執行拷貝,我在下面做了這個;

VB.NET Error In Picture Format

畫面基本上是說有關文章標題〜壞圖像格式異常。錯誤代碼:0x8007000B。

這是一個通用的錯誤,只有很少的信息,因爲它適用於各種場景。但是,我可以放心地假設,它與指針有關。

我想要的是一個快速的ASM模塊來執行通用內存拷貝,但對於vb.NET圖像。

任何提示,堆棧溢出!

+0

http://shotting.cc/soapbox/viewtopic.php?f=20&t=10&p=11#p11這是指向作者原始帖子的鏈接。 –

+0

不知道它是否與問題有關,但第一個參數是放置數據的_destination bitmap_,第二個參數是將從中複製數據的_source位圖。目前您正在嘗試將空白位圖複製到非空白位圖。 –

+0

道歉,VVincent,在圖像代碼中的錯誤。 bm2

回答

1

當您嘗試加載程序集或dll時編譯的應用程序位數不同時,會引發A BadImageFormatException。例如,如果您嘗試在64位應用程序中加載32位dll(反之亦然)。

確保dll編譯的位數與應用程序相同。如果應用程序被編譯爲AnyCPU然後要麼迫使它是x86x64編譯使用每個位數兩個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 

編輯:

根據漢斯帕桑特,ASM MMX指令不能在64使用,所以我的解決辦法以上不適合你。但是我將它留在那裏,因爲它適用於使用本機C/C++代碼編譯的DLL。

+1

該解決方案無法工作,彙編代碼只能運行在32位進程中。 MMX指令已在x64中停用。只有好的建議是完全消除它,因爲它沒有妥善處理對齊問題,所以它不是最佳代碼。並且很難正確使用內存損壞的高可能性,截圖中的「100」參數完全是任意的。 Marshal.Copy()和System.Buffer類沒有的問題。 –

+0

@HansPassant:我沒有意識到這一點。謝謝! –

+0

@HansPassant:也許你應該寫一個關於它的答案?我不熟悉ASM或其實現。 –

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 ^增量通過數組來讀取。

很簡單,呃?

+0

感謝您的幫助。我很驚訝MMX指令在x64中已經停止使用,因爲x64體系結構書是我進行MMX複製操作的地方。也就是說,我正在x64位機器上實現這個x86代碼(32位)。看到,當升級發生時,沒有任何東西真的被遺漏在Intel CPU上。這就是爲什麼在一臺x64拱形機器上,儘管我們不再需要這樣做,但它仍然有可能使用mov al,bl。此外,MMX指令可在x64機器上使用〜但是作爲32位體系結構的副產品。例如,mm7寄存器的大小爲64位,因爲rax寄存器爲64位。 –

+0

@ shotting.cc:你剛剛在不同的帳戶下回答自己的問題嗎?在回答者的標題中,它說「shotting.cc」。僅供參考如果是你,你可以用同一個帳戶回答你自己的問題。 –

+0

嗨文森特,我在不同的位置在不同的計算機上沒有正確的登錄細節,所以我用我的Google帳戶發佈答案。 –