C# - C 互操作性

3

这个链接中的问答很接近我想要的,但是我刚刚开始学习C#,需要更多的填充和一些关于继续进行的最佳方法的提示。

我编写了一个适用于PalmPre/webOS的应用程序,其中一部分是以便携性而非性能的考虑用C编写的。它执行Lear Jet性能计算。

在webOS世界中,C代码(插件)位于其自己的进程中,并且有一种方式让JS调用并调用C代码(使用'main')来启动进程,C可以注册入口点。然后,JS可以使用一些参数调用入口点,C代码进行计算,然后C返回指向数字字符串的指针以供JS显示。 C代码没有图形,没有动态内存分配等。我想将JS GUI代码基本转换为C#,并使用稍微调整(#if)的C代码来做与现在Pre上的JS相同的事情。

我认为答案1/option2是最好的选择,但我不明白他所说的“你的项目vs使用者项目”以及为什么这意味着一个是dllimport,而另一个是dllexport,而我没有DLL,我只有C代码例程。看起来我只需要用我的C例程替换他的“PublicFunc”,对吗?而在‘params’处,我可以有许多参数吗?但是没有指定返回类型,我该如何将答案返回给C#?‘returntype’是保留字吗?还是示例占位符?还是因为我没有DLL而偏离了轨道?BTW,C代码有一种模式,可以编译为独立运行的DOS程序进行测试。

有没有什么简单的示例代码可以说明如何做到这一点?我正在下载MS VS 2010 Express,尚未安装。也许那里有什么东西?

TIA!


如果我理解正确,那个 MSDN 链接是关于 C++ -> C 的链接,是否有类似的东西来说明 C# -> C 的神奇咒语细节呢? - Paul Kinzelman
1
哦,你说得对。无论如何,C#也使用 DllImport 属性。这里有一个带有 C#/C 示例的链接(向下滚动):http://www.csharphelp.com/2006/12/c-tutorial-for-beginners/ - user568493
是的,这更像样了!当我需要它时,我得消化一下。我很惊讶他们在初学者教程中包含了一个C#/C链接示例,听起来这是一个相当普遍的事情。 - Paul Kinzelman
我也会查阅“编组”(marshalling)相关资料。由于托管代码中的变量(C#具有管理代码执行的运行时)可以随意移动,并且也可以随意清理它们(C#的“等效项”是C++中的“free()”,即垃圾回收-为您的处理进程提供整个“特殊线程”),因此C#的编组运行时非常强大,但如果/当开始传递指针时会发生奇怪的事情。 - Aidanapword
希望你不是在尝试为Windows Phone 7做这个,因为你的C dll在那里无法运行。 - Julien Roncaglia
显示剩余2条评论
3个回答

3

感谢所有回答的人,每个回答都有一点答案。因此,为了那些可能会遇到相同问题的人,我将发布我编写的代码以尝试我所需的链接。

//以下是C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;     // DLL support
namespace ConsoleApplication1
{
  class Program
  {
    [DllImport("dodll.dll",
           CallingConvention = CallingConvention.Cdecl)]
    [return: MarshalAs(UnmanagedType.LPStr)]
    private static extern string dodll(int a, int b,
                       [MarshalAs(UnmanagedType.LPArray)] float[] nums,
                       [MarshalAs(UnmanagedType.LPStr)] string strA,
                       [MarshalAs(UnmanagedType.LPStr)] string strB);

static void Main(string[] args)
{
  int x = 2; int y = 3;
  float[] numbers = new float[3]{12.3F, 45.6F, 78.9F};
  float[] simargs = new float[20];

  string strvarA = "Test string A";
  string strvarB = "Test another string";
  string answer = dodll(x, y, numbers, strvarA, strvarB);
  Console.WriteLine("hello world " + answer);
  Console.WriteLine("another hello world" + x);
  Console.WriteLine("End of sim");
}

//这是C代码(DLL):

#include <stdio.h>
char astring[50];
//Passing structure pointer info: http://www.adp-gmbh.ch/win/misc/mingw/dll.html
extern "C"
{  __declspec(dllexport) 
char* dodll( long a, long b, float* aptr, char* sa, char* sb)
{
    float nums[3];
    nums[0] = *aptr;
    nums[1] = *(aptr+1);
    nums[2] = *(aptr+2);
  sprintf(astring, "Building string: %s %s %ld, nrs are %2.1f, %2.1f, %2.1f.\n",
  sa, sb, (a+b), nums[0], nums[1], nums[2]);
  printf("Inside DLL: %s\n", astring);
  return astring;
}
}

0
补充说明...我最近发现Windows Phone 7 C#/XAML不支持与C/C++链接,这让我原本想做的事情泡汤了。显然,所有东西都必须用C#编写,而我不打算将所有图形分析代码和数据库重写为C#,所以我会转向Android。

0
我会从这里开始: Interop的MSDN ...一定要选择所需的VS版本(2005/2008/2010)... :)

我在其他地方听到的一切都说Windows Phone不支持C#-C链接,所以如果您有相反的信息,请告诉我。我在您提供的链接中没有找到任何相关信息。谢谢! - Paul Kinzelman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接