Xamarin 有助于在移植到 android 的共享库的 win32 DLL 吗?

发布时间: 2014/3/4 8:04:51
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我在一个项目,我需要在其中 Android 应用程序中包括 NGSpice 仿真库和当然能够使用它。

我需要到端口的NGSpice窗口 DLL,我的 android 应用程序,多远会xamarin帮我在这项任务吗?它是 win32 dll,它不是.Net 基于 dll,请看一下NGSpice链接

谢谢你。

解决方法 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 生成
  8. 一旦 ndk 生成成功完成创建 C# 项目目录内的子文件夹lib和复制生成的本机库,包括其周围到lib文件夹。您的文件夹结构应该看起来像这样: < 项目 > -> libs -> armeabix 86 (两个文件夹都包含一个 architure 具体.so 文件)。通过建立这个文件夹结构,我们确保 MonoDroid 将自动加载当前运行时体系结构匹配的库。
  9. 创建新的 C# 类文件Foo.cs在 C# 项目内部。此类实现您的本机库包装和 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 生成您希望支持的体系结构。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
}
赞助商