2015-05-20 6 views
4

Я пытаюсь включить C++ библиотека (DLL) в моем C# проекта, но каждый раз, когда я делаю, что я получаю следующее сообщение об ошибке в VS2012Как использовать C библиотеки DLL ++ из C#

A reference to 'C:\Users\HiepDang\Desktop\mydll.dll' could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component. 

Когда я пытаюсь добавить Com + Component, появляется следующее сообщение об ошибке в окне

Один или несколько файлов не содержат библиотек компонентов или типов. Эти файлы не могут быть установлены.

Ошибка 80110425 произошла.

Произошла неизвестная ошибка. Вы должны проверить всю документацию для решения. Если дополнительная информация не доступна, пожалуйста, контракт технической поддержки в

Я следующий поток here и here, но моя проблема не решена.

В C++, я могу использовать DLL, как:

//Header 
    extern "C" __declspec(dllimport) int mymethod(const char *key, char *data, size_t buflen); 

    //Code test 
    const char* key = "test"; 

    char* data = new char[1024]; 
    int buflen = 1024; 
    int result = mymethod(key,data, buflen); 

В C#, я использую библиотеку DLL, как:

//define dll 
    [DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 
    public static extern int mymethod([MarshalAs(UnmanagedType.LPTStr)]string key, [MarshalAs(UnmanagedType.LPTStr)]string data, uint buflen); 

    //method test 
    private static int testdll() 
    { 
     string key = "123456789"; 
     string buf = string.Empty; 
     mymethod(key, buf, 1024); 
     return 0; 
    } 

Можете ли вы сказать мне какие-либо решения, чтобы решить эту проблему.

P.s: Мой английский не очень хорошо. Прошу прощения, если что-то неудобно

Отредактировано: Я объясняю переменную в методе в dll. «ключ», поскольку ввод строки имеет 8-13 символов, mymethod будет зашифрован для генерации «buf». Мне нужна переменная «buf».

+1

Как говорят ссылки, используйте 'DllImport'. ** Не пытайтесь добавить ссылку, щелкнув правой кнопкой мыши ** Ссылки ** и выбрав * * Добавить ** Просто используйте существующий код 'DllImport' C# – MickyD

+0

@MickyDuncan: Спасибо за ответ, но код C#, который я опубликовал, не соответствует моему требованию. Когда вызов mymethod, значение« buf »должно измениться. Следуйте C# -коду, Я просто получаю сообщение об ошибке, что «значение« ключ »недопустимо». Это происходит, когда переменная ключа недостаточно 8 символов. –

+0

Обновите свой вопрос, чтобы отразить эти новые требования – MickyD

ответ

2

В C# вы должны использовать StringBuilder()

//define dll 
[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 
public static extern int mymethod(string key, StringBuilder data, IntPtr buflen); 

//method test 
private static int testdll() 
{ 
    string key = "123456789"; 
    StringBuilder buf = new StringBuilder(1024); 
    mymethod(key, buf, (IntPtr)buf.Capacity); 
    string buf2 = buf.ToString() 
    return 0; 
} 

Обратите внимание, что size_t в размере IntPtr, потому что это 4 байта на x86 и 8 байт на x64.

+0

Спасибо за ваши решения. Я должен был следовать, но все же произошла ошибка. –

+0

@HiepDang Вы должны поместить '.dll' в ту же папку' .exe', и вам нужно знать, была ли ваша '.dll' скомпилирована в 32 бита или 64 бит. Затем установите для проекта C# значение Properties-> Build-> Platform Target x86, если dll - 32 бита и x64, если dll - 64 бита. – xanatos

+0

mydll - 32 бит, тогда я также установил платформу Target x86. Я думаю, что я должен использовать C++/CLI, чтобы решить эту ошибку. Спасибо за помощь! –

1

В вашем CPP проекте изменение

extern "C" __declspec(dllimport) 

в

extern "C" __declspec(dllexport) 

И скопировать сгенерированный CPP DLL файл "MyDLL.dll" в OUTDIR вашего проекта C#.

Кстати, вам лучше использовать байт [] вместо char * для данных второго аргумента, если это не строка, а исходные двоичные данные.

[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern int mymethod([MarshalAs(UnmanagedType.LPTStr)]string key, byte[] data, uint buflen); 

байт массив автоматически сортируется.

Reference on MSDN

Используйте его, как показано ниже.

var key = "A key"; 
var data = new byte[10]; 
//fill data 
mymethod(key, data, (uint)data.Length); 
+0

Не так, как вы думаете. Cpp-фрагмент кода, который вы видите в Visual C++, и он может работать хорошо. Но я хочу использовать mydll.dll в C#, и я не знаю, как это сделать? –

0

Кроме того, потому что моя DLL является неуправляемым (это означает, что это неуправляемый язык, как C или C++), то в соответствии с спецификации DllImport, «Указывает, что приписывали метод подвергается с помощью неуправляемых DLL в качестве статической точки входа ». Почему я не могу использовать этот «DllImport»? Если его объект C++ com, если вы зарегистрируете его с помощью regsvr32, вы можете добавить ссылку на DLL на вкладку ссылок Visual Studio com, и обычно визуальная студия создает dll (я думаю, что это называется оболочкой, вызывающей вызов), которую вы видите с именемoflibrary.interop.dll. Таким образом, MyExecRefsDll.dll, если был комком, станет MyExexRefs.Interop.dll. Но когда вы добавляете эталонную визуальную студию, вы автоматически делаете это автоматически в управляемом коде. Если вы создаете dll C++ в качестве объекта com, используя шаблон atl в C++, проще получить доступ из dotnet (Iam, ссылающийся на неуправляемый код C++ из dll, который ссылается на другой файл dll.) Нет кода, скопированного со второй dll. Я просто ссылаюсь на tlb , lib, dll-файл и визуальная студия делают все остальное.

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