Управляемое приложение Visual C ++: невозможно найти точку входа с именем «Добавить»

Я следовал руководству на следующей странице, чтобы создать DLL-библиотеку c ++, и поместил ее в папку System32:http://msdn.microsoft.com/en-us/library/ms235636%28v=vs.80%29.aspx, Я могу запустить .exe из любого места на ПК. Теперь я хочу иметь возможность вызывать Add из приложения VB.NET, поэтому я добавил следующий код:

Imports System.Runtime.InteropServices

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Try
            Dim Test As Integer
            Test = Add(1, 1)
            MsgBox(Test)
        Catch ex As Exception

        End Try
    End Sub

    <DllImport("MathFuncsDll.dll", EntryPoint:="Add", SetLastError:=True, CharSet:=CharSet.Ansi)> _
    Private Shared Function Add(ByVal a As Double, ByVal B As Double) As Double
    End Function

End Class

Я получаю следующую ошибку: Невозможно найти точку входа с именем «Добавить» в DLL «MathFuncsDll.dll». Я считаю, что это из-за пространства имен. Я исследовал это, и некоторые веб-страницы говорят, что пространства имен запрещены с помощью Platform Invoke, а некоторые веб-страницы говорят, что они разрешены. В чем проблема?

Ответы на вопрос(2)

Решение Вопроса

запуститеdumpbin /exports MathFuncsDll.dll чтобы увидеть экспортированные имена. Чтобы получить эту декларацию:

<DllImport("MathFuncsDll.dll", EntryPoint:="[email protected]@[email protected]@[email protected]", _
           CallingConvention:=CallingConvention.Cdecl)> _
Private Shared Function Add(ByVal a As Double, ByVal B As Double) As Double
End Function

Странно выглядящее имя создается компилятором C ++, функцией под названием «оформление имени». Поддерживает перегрузку функций. Вы можете положитьextern "C" перед объявлением функции, чтобы подавить его. Это на самом деле лучше, если вы этого не сделаете. Также обратите внимание, что SetLastError не был корректным, код фактически не вызывает SetLastError () для сообщения об ошибках. И CharSet не подходит, эти функции не принимают строки.

Вам также нужно будет что-то сделать с функцией Divide, если исключение C ++ не приведет к хорошему завершению в сценарии взаимодействия, только код C ++ может его перехватить.

 w005197714 окт. 2012 г., 21:07
Спасибо за исправление.
 w005197714 окт. 2012 г., 20:43
Благодарю. +1 за ссылку на dumpbin.exe. Я сделал то, что вы предложили, и теперь ошибка: «WindowsApplication1.Form1 :: Add 'разбалансировал стек. Это, вероятно, потому, что управляемая подпись PInvoke не соответствует неуправляемой целевой подписи. Проверьте, что соглашение о вызовах и параметры PInvoke»
 Hans Passant14 окт. 2012 г., 21:04
Почти там, соглашение о вызовах не __stdcall. Пост исправлен.

C. Не забудьте также объявить MathFuncsDll как extern «C», чтобы предотвратить искажение имени в C ++. Используйте Dependency Walker или dumpbin, чтобы увидеть список функций, экспортированных из MathFuncsDll.

 Alex F14 окт. 2012 г., 21:24
Конечно, если вы используете украшенные имена в объявлении PInvoke. Классический способ - использовать extern «C», это выглядит лучше. Декорированные имена используются в PInvoke в основном, когда нам нужно использовать стороннюю библиотеку без исходного кода, которая экспортирует функции C ++.
 w005197714 окт. 2012 г., 21:11
Спасибо за ответ, но, пожалуйста, смотрите ответ Ханса Пассанта. Похоже, что можно использовать пространства имен.

Ваш ответ на вопрос