2013-04-10 5 views
6

Я знаю this similar question, но он не отвечает на мою проблему.Как использовать dll C++ в Unity3D?

Я написал два .dll с помощью Visual Studio 2010. Один из них находится на C++ и общается с SDK, написанным на C++. Другой - это C# -компьютер для этой библиотеки C++, так что он может использоваться в контекстах C#.

Мой план состоял в том, что это позволило мне использовать мой код в Unity3D, но, видимо, это не тот случай. Кажется, Unity3D не позволяет мне импортировать .dll s как активы, если они не являются .NET сборкой. Поэтому я могу добавить свою оболочку C#, но не C++ dll.

Это приводит к DllNotFoundException всякий раз, когда я пытаюсь получить доступ к библиотеке C++. Я попытался просто скопировать библиотеку C++ в папку Assets/Plugins, но это дает те же результаты.

Есть ли способ сделать это правильно? Это очень важная часть моей настройки проекта.

+0

Как вы называете C++ DLL? Вам не нужно добавлять его в свое решение в качестве ссылки .. это родной ресурс. –

+0

@SimonWhitehead Я использую 'PInvoke' для вызова функций C++ с помощью' [DllImport ("Foo.dll")] '. Он работает, когда две библиотеки DLL находятся в одной папке, но я понятия не имею, как Unity обрабатывает плагины dlls. –

+0

Какую лицензию вы используете? Какова ваша цель? – aukaost

ответ

5

Проблема в том, что DLL не найдена, когда код выполнения p/invoke вызывает LoadLibrary(YourNativeDllName).

Вы можете решить эту проблему, убедившись, что ваша DLL находится на пути поиска DLL в точке, где выполняется первый вызов p/invoke. Например, позвонив по номеру SetDllDirectory.

Решение, которое я лично предпочитаю, - это ваш управляемый код для p/вызова вызова LoadLibrary, передающего полный абсолютный путь к родной DLL. Таким образом, когда последующий вызов p/invoke вызвал LoadLibrary(YourNativeDllName), ваша собственная DLL уже находится в процессе и поэтому будет использоваться.

internal static class NativeMethods 
{ 
    [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)] 
    internal static extern IntPtr LoadLibrary(
     string lpFileName 
    ); 
} 

А потом где-то в коде:

private static IntPtr lib; 

.... 

public static void LoadNativeDll(string FileName) 
{ 
    if (lib != IntPtr.Zero) 
    { 
     return; 
    } 

    lib = NativeMethods.LoadLibrary(FileName); 
    if (lib == IntPtr.Zero) 
    { 
     throw new Win32Exception(); 
    } 
} 

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

+0

Могу ли я использовать абсолютный путь к библиотеке для этого? Я не единственный человек, работающий над этим проектом, так что это сделает вещи очень сложными ... –

+0

Ну да. Но это не значит, что вам нужно жестко закодировать путь. Вы можете создать его во время выполнения. Поместите родную DLL в ту же папку и управляемую DLL, и создайте путь таким образом. В ваших объявлениях p/invoke по-прежнему используется только имя DLL, то есть '' mydll.dll''. Но не исключено, что система должна как-то найти вашу DLL. Вы не можете просто разместить DLL в любом месте и надеяться, что система найдет его для вас. –

+0

Я знаю, что я не могу просто случайно разместить его где угодно; Я надеялся, что Unity3D позволит мне указать его как зависимость каким-то образом, чтобы получить доступ к нему способом, похожим на способ доступа к C#.Когда вы говорите, что я могу создать путь во время выполнения, как вы предлагаете мне это сделать? Unity3D перемещает мою dll, как только он был импортирован в качестве плагина, поэтому я не уверен, как я могу это сделать. –

0

Обратите внимание, что исключение DllNotFoundException может быть вызвано созданием вашей Unity DLL в Debug вместо Release!

Простой надзор, который может вызвать головную боль.

Смежные вопросы