【问题标题】:Would Xamarin help in porting win32 DLL to android shared library?Xamarin 会帮助将 win32 DLL 移植到 android 共享库吗?
【发布时间】:2013-10-23 10:42:12
【问题描述】:

我正在做一个项目,我需要在 Android 应用程序中包含 NGSpice 模拟库,并且当然能够使用它。

我需要将NGSpice windows DLL 移植到我的 android 应用程序,xamarin 能在多大程度上帮助我完成这项任务?它是一个 win32 dll,它不是基于 .Net 的 dll,请查看 NGSpice 链接

谢谢。

【问题讨论】:

  • 我认为,只要编译目标是 arm 就应该可以工作
  • windows dll 将无法工作。由于android是arm平台,所以需要编译arm的源码。
  • 我问的是使用 xamarin,它会是解决方案吗?我的项目有数千个文件分散在文件夹中
  • 不,您的问题与 Xamarin 无关。如果您有现有的 .Net 托管代码(F#、C# 等),Xamarin 会很有帮助,但对 C/C++ 没有任何特殊作用。

标签: android android-ndk xamarin


【解决方案1】:

是的,可以使用Android NDK

由于阅读所有文档一开始可能会有点不知所措,所以我将带您快速浏览一下。

  1. 安装 NDK
  2. 在您的项目目录中创建一个名为 jni 的文件夹
  3. 在该文件夹内创建一个子文件夹 lib 并将库的所需源文件复制到该文件夹​​
  4. jni 文件夹中创建两个文件,wrapper.c 和 wrapper.h。这些文件应该包含适用于使用 DllImport 从 C# 端绑定的原生库的高级包装器
  5. jni 文件夹中创建一个名为 Android.mk 的文件
  6. jni 文件夹中创建一个名为 Application.mk 的文件
  7. 运行 ndk-build
  8. ndk-build 成功完成后,在您的 C# 项目目录中创建子文件夹 lib,并将生成的本机库(包括其周围的文件夹)复制到 lib。您的文件夹结构应如下所示: -> libs -> armeabix86(两个文件夹包含特定于架构的 .so 文件)。通过建立这个文件夹结构,我们确保 MonoDroid 会自动加载当前运行时架构的匹配库。
  9. 在您的 C# 项目中创建新的 C# 类文件 Foo.cs。此类实现了本机库包装器和 C# 世界之间的绑定胶水。
  10. 利润!

Android.mk:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := libFoo
LOCAL_SRC_FILES := wrapper.c lib/source1.c lib/sourcen.c

include $(BUILD_SHARED_LIBRARY)

注意: lib/source1.c 和 lib/sourcen.c 需要替换为您的实际库源文件的名称。

Application.mk:

APP_ABI := armeabi armeabi-v7a x86

这一行告诉 ndk-build 您希望支持哪些架构。 x86 适用于英特尔 Android HAXM 模拟器。

wrapper.h:

#pragma once

typedef struct _InternalState
{
    FILE *m_pFile;
} InternalState;

//////////////////////
// Public API

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

InternalState *FooCreate(int foo);
void FooDoStuff(InternalState *pState);

#ifdef __cplusplus
}
#endif /* __cplusplus */

wrapper.c:

//////////////////////
// Public API

InternalState *FooCreate(int foo)
{
  // Initialize actual library here
  // return state if necessary
}

void FooDoStuff(InternalState *pState)
{
  // Call actual library here
}

Foo.cs:

public class Foo :
  IDisposable
{
  private IntPtr handle;
  private bool disposed;

  private Foo(IntPtr handle)
  {
    this.handle = handle;
  }

  ~Foo()
  {
    Dispose(false);
  }

  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }

  public void Dispose(bool disposing)
  {
    disposed = true;

    Close();
  }

  #region Native Imports

  [DllImport("libFoo")]
  private static extern IntPtr FooCreate(int seed);
  [DllImport("libFoo")]
  private static extern void FooDoStuff(IntPtr pHandle);

  #endregion

  private void VerifyHandle()
  {
    if (handle == IntPtr.Zero)
      throw new InvalidOperationException("Handle not initialized");
  }

  #region Public API

  public static Foo FromSeed(int seed)
  {
    IntPtr handle = FooCreate(seed);
    if(handle == IntPtr.Zero)
      throw new System.Exception("Failed to create native object");

    return new Foo(handle);
  }

  public void DoStuff()
  {
    VerifyHandle();

    FooDoStuff(handle);
  }

  #endregion
}

【讨论】:

  • 谢谢,但我问的是xamarin工具,我不想进入修复错误的过程..尤其是那些与windows相关的..
  • 没有这个工具。
  • 其实我是问这个xamarin.com,真的能解决我的问题吗?
  • 根据 NGSpice 文档,该库是跨平台的。因此,我的帖子中概述的步骤应该适用。但是你并不需要 MonoDroid,除非你想在 C# on Android 中使用那个库。
猜你喜欢
  • 1970-01-01
  • 2010-09-10
  • 2011-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多