2016-11-13 3 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 ERR: 0x8007000B (Bad Image Format Exception)

Я успешно импортирован этот .dll в консольное приложение C++ и скопировать строку 'Hello World' из char * a, char * b. Затем повторил b, успешно показав «Hello World».

Тогда, поскольку это обычная программа копирования памяти, которая принимает два указателя для выполнения копии, я сделал это ниже;

VB.NET Error In Picture Format

Картина в основном говорит о ДОЛЖНОСТЬ ~ Bad Image Format Exception. Код Err: 0x8007000B.

Это общая ошибка с небольшой информацией, поскольку она применима к различным сценариям. Но, я могу смело предположить, что-то связано с указателями.

Что я хочу - это быстрый модуль ASM для выполнения копий общей памяти, но для изображений vb.NET.

Любые советы, переполнение стека!

+0

http://shotting.cc/soapbox/viewtopic.php?f=20&t=10&p=11#p11 Это ссылка на исходное сообщение авторов. –

+0

Не знаю, связано ли это с проблемой, но первым параметром является битмап _destination_, где будут помещаться данные, а вторым параметром является битмап _source_, из которого будут скопированы данные. И в настоящее время вы пытаетесь скопировать пустую растровую карту на непустую. –

+0

Извинения, VVincent, за ошибку в коде изображения. Результат тот же для bm2

ответ

1

A BadImageFormatException вызывается при попытке загрузить сборку или библиотеку dll, которая скомпилирована под другой битностью, чем приложение. Например, если вы попытаетесь загрузить 32-разрядную dll в 64-битном приложении (или наоборот).

Убедитесь, что 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 

EDIT:

По словам Ханса Passant, инструкции ASM MMX не могут быть использованы в 64, так что мое решение выше не будет работать для вас. Однако я оставляю его там, потому что он работает для DLL, скомпилированных с использованием собственного кода C/C++.

+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. Тем не менее, я очень хорошо реализую этот x86-код (32-разрядный) на x64-разрядных машинах. Понимаете, ничто не оставляет в стороне процессор Intel, когда происходят обновления. Вот почему на машине с архитектурой x64 можно сделать все возможное, хотя нам вряд ли нужно это делать. Кроме того, инструкции MMX доступны на x64 машинах ~, но в качестве побочного продукта 32-разрядной архитектуры. Например, регистр mm7 имеет размер 64 бит, так как регистр rax является 64-битным. –

+0

@ shotting.cc: Вы только что ответили на свой вопрос под другой учетной записью? В заголовке ответчика говорится «shotting.cc». FYI, если это был вы, вы можете ответить на свой вопрос с той же учетной записью. –

+0

Привет, Винсент, я был на другом компьютере в другом месте без правильных данных для входа, поэтому я использовал свой аккаунт Google, чтобы опубликовать ответ. –