2013-12-03 3 views
2

Я использую VS2012 и пытаюсь вызвать функцию в проекте C# из C DLL, которую я написал. C DLL вызывается внешним приложением (Thunderbird).Вызов C# DLL с C; связанные проблемы

Я нашел страницу Unmanaged Exports и выполнил инструкции. В процессе мой проект C# должен был быть установлен на .net4 и x86, чтобы получить все, чтобы скомпилировать и связать, насколько это возможно. Но у меня ошибка компоновщика, которую я не могу решить, и поскольку для меня это неизведанная территория, возможно, я просто делаю что-то глупое.

В моем C# у меня есть;

using RGiesecke.DllExport; 

namespace StreamAttacher 
{ 
    class Test 
    { 
     [DllExport("add", CallingConvention = CallingConvention.Cdecl)] 
     public static int TestExport(int left, int right) 
     { 
      return left + right; 
     } 
    } 
} 

И в моей C У меня есть

#include<stdio.h> 

int add(int left, int right); //in c# 

__declspec(dllexport)char* strTest2() 
{ 
    int i = add(2,3); 
    char *p = "C:\\Work\\Mozilla\\Test dir\\testfile.zip"; 
    return p; 
} 

Проект C# ссылается на проект C в его внешних зависимостей.

На здании, я получаю ошибку «линкер LNK2019 ошибки: неразрешенный внешний символ _ADD ссылки в функции _strTest2»

Если я смотрю на C# DLL, используя DllExp то я не вижу ничего экспортировали. Нужно ли мне? Я ожидал увидеть функцию «добавить», но ее там нет, и никаких ошибок не возникает, когда я создаю C# DLL самостоятельно.

Кроме того, это то, что proto для 'add' в коде C все, что мне нужно, если что-то работает дальше дальше по цепочке?

+1

Вам нужна библиотека импорта для DLL, чтобы сохранить компоновщик счастливым. У вас его нет, и вы не можете получить его от этой утилиты. Запись файла .def и преобразование его в библиотеку импорта технически возможна, хотя и очень подвержена ошибкам. Это просто не очень практично для реальных приложений. Используйте [неуправляемый способ] (http://stackoverflow.com/a/2082212/17034). –

ответ

1

Недавно я попробовал экспортировать функции C# для той же цели (используя библиотеку RGiesecke и другие методы), не смог заставить ее работать и нашел ее очень волосатой. Если у вас есть возможность попробовать что-то еще, я бы предложил посмотреть на создание библиотеки C++/CLI вместо промежуточного. Для меня это гораздо более приемлемое решение.

Вот достойный учебник: http://www.codeproject.com/Articles/19354/Quick-C-CLI-Learn-C-CLI-in-less-than-10-minutes

+0

Спасибо, это и комментарий от @HansPassant сделали мне еще один шаг вперед. –

0

Вы можете определить свой C# подписи с использованием сортировочными атрибутов для ваших строковых параметров.

[DllImport(@"c:\GDAit.dll")] 
public static extern long TransGeogPt([MarshalAs(UnmanagedType.LPStr)] string sGridFile, long lDirection, double dLat, double dLong, ref double pdLatNew, ref double pdLongNew, ref double pdLatAcc, ref double pdLongAcc); 

[DllImport(@"c:\GDAit.dll")] 
public static extern long TransProjPt([MarshalAs(UnmanagedType.LPStr)] string sGridFile, long lDirection, double dLat, double dLong, long lZone, ref double pdLatNew, ref double pdLongNew, ref double pdLatAcc, ref double pdLongAcc); 

Я также контрейлерных на ответ Марка Sowul и сказать, попробуйте позвонить с STDCALL вместо Cdecl.

Кроме того, в качестве меры предосторожности, я бы, наверное, дважды проверьте, чтобы убедиться, что компилятор настроен для компиляции x86 кода, в случае его компиляции для 64-битного.

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