概述
本文档详细介绍如何在KMP项目中集成现有的C++库,通过分层架构实现iOS和Android平台的代码共享。以字符串相似度计算为例,展示完整的iOS调用流程。
整体架构图
iOS (Swift) → KMP自动生成胶水层 → C胶水层 → C++核心库
C++核心库实现
1. 头文件定义 (levenshtein.h)
#ifndef LEVENSHTEIN_H
#define LEVENSHTEIN_H
#include <string>
class StringProcessor {
public:
StringProcessor(const std::string& baseStr);
double calculateSimilarity(const std::string& target) const;
private:
std::string baseString;
int computeEditDistance(const std::string& a, const std::string& b) const;
};
#endif
2. 实现文件 (levenshtein.cpp)
#include "levenshtein.h"
StringProcessor::StringProcessor(const std::string& baseStr) : baseString(baseStr) {}
double StringProcessor::calculateSimilarity(const std::string& target) const {
if (baseString.empty() && target.empty()) return 1.0;
int maxLen = (baseString.length() > target.length()) ? baseString.length() : target.length();
int distance = computeEditDistance(baseString, target);
return 1.0 - (static_cast<double>(distance) / maxLen);
}
int StringProcessor::computeEditDistance(const std::string& a, const std::string& b) const {
if (a == b) return 0;
return (a.length() > b.length()) ? a.length() - b.length() : b.length() - a.length();
}
C胶水层开发
1. C接口声明 (string_glue.h)
#ifndef STRING_GLUE_H
#define STRING_GLUE_H
#ifdef __cplusplus
extern "C" {
#endif
typedef void* StringProcessorHandle;
StringProcessorHandle create_processor(const char* base);
double calc_similarity(StringProcessorHandle handle, const char* target);
void destroy_processor(StringProcessorHandle handle);
#ifdef __cplusplus
}
#endif
#endif
2. C++实现 (string_glue.cp)
#include "string_glue.h"
#include "levenshtein.h"
extern "C" {
StringProcessorHandle create_processor(const char* base) {
try {
return new StringProcessor(std::string(base));
} catch (...) {
return nullptr;
}
}
double calc_similarity(StringProcessorHandle handle, const char* target) {
if (!handle || !target) return -1.0;
StringProcessor* processor = static_cast<StringProcessor*>(handle);
try {
return processor->calculateSimilarity(std::string(target));
} catch (...) {
return -1.0;
}
}
void destroy_processor(StringProcessorHandle handle) {
if (handle) {
delete static_cast<StringProcessor*>(handle);
}
}
}
KMP配置与封装
1. Gradle配置 (build.gradle.kts)
kotlin {
iosX64()
iosArm64()
sourceSets {
val iosMain by getting {
dependencies {
implementation(kotlin("stdlib"))
}
}
}
targets.withType<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget> {
binaries.withType<org.jetbrains.kotlin.gradle.plugin.mpp.Framework> {
linkerOpts.add("-lstdc++")
}
}
}
2.Kotlin封装类 (StringProcessor.kt)
import kotlinx.cinterop.*
import platform.Foundation.*
import stringglue.*
class NativeStringProcessor(private val base: String) : AutoCloseable {
private val processorRef: CPointerVarOf<Any> = interpretCPointer(
create_processor(base)?.ptr
)!!
fun calculateSimilarity(target: String): Double {
return memScoped {
val result = target.utf8CString { cString ->
calc_similarity(processorRef.rawValue.toLong(), cString.ptr)
}
result
}
}
override fun close() {
destroy_processor(processorRef.rawValue.toLong())
}
}
iOS Swift调用
import SharedKit
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let processor = NativeStringProcessor(base: "HelloWorld")
let similarity = processor.calculateSimilarity(target: "Hello KMP")
print("相似度: $similarity)")
// processor.close() // 手动释放资源
}
}
项目结构
shared/
├── src/
│ ├── nativeInterop/
│ │ └── c/
│ │ ├── include/
│ │ │ ├── levenshtein.h
│ │ │ ├── levenshtein.cpp
│ │ │ ├── string_glue.h
│ │ │ └── string_glue.cpp
│ │ └── def/
│ │ └── stringglue.def
│ └── commonMain/
│ └── kotlin/
│ └── StringProcessor.kt