【发布时间】:2019-10-18 08:38:18
【问题描述】:
我正在尝试使用本机库来修改字节数组(实际上是 uint16 数组)的内容。我有 Unity (C#) 中的数组和 C++ 中的本机库。
我已经尝试了几件事,我能做到的最好的方法是成功调用本机代码并能够将布尔值返回给 C#。当我传递一个数组并在 C++ 中对其进行变异时,问题就来了。无论我做什么,该数组在 C# 中都未修改。
这是我在 Unity 方面的内容:
// In Update().
using (AndroidJavaClass processingClass = new AndroidJavaClass(
"com.postprocessing.PostprocessingJniHelper"))
{
if (postprocessingClass == null) {
Debug.LogError("Could not find the postprocessing class.");
return;
}
short[] dataShortIn = ...; // My original data.
short[] dataShortOut = new short[dataShortIn.Length];
Buffer.BlockCopy(dataShortIn, 0, dataShortOut, 0, dataShortIn.Length);
bool success = postprocessingClass.CallStatic<bool>(
"postprocess", TextureSize.x, TextureSize.y,
dataShortIn, dataShortOut);
Debug.Log("Processed successfully: " + success);
}
Unity 项目在 Plugins/Android 中有一个 postprocessing.aar,并且已为 Android 构建平台启用。 我在 Java 中有一个 JNI 层(调用成功):
public final class PostprocessingJniHelper {
// Load JNI methods
static {
System.loadLibrary("postprocessing_jni");
}
public static native boolean postprocess(
int width, int height, short[] inData, short[] outData);
private PostprocessingJniHelper() {}
}
上面的 Java 代码在 C++ 中调用了这段代码。
extern "C" {
JNIEXPORT jboolean JNICALL POSTPROCESSING_JNI_METHOD_HELPER(postprocess)(
JNIEnv *env, jclass thiz, jint width, jint height, jshortArray inData, jshortArray outData) {
jshort *inPtr = env->GetShortArrayElements(inData, nullptr);
jshort *outPtr = env->GetShortArrayElements(outData, nullptr);
jboolean status = false;
if (inPtr != nullptr && outPtr != nullptr) {
status = PostprocessNative(
reinterpret_cast<const uint16_t *>(inPtr), width, height,
reinterpret_cast<uint16_t *>(outPtr));
}
env->ReleaseShortArrayElements(inData, inPtr, JNI_ABORT);
env->ReleaseShortArrayElements(outData, outPtr, 0);
return status;
}
核心 C++ 函数 PostprocessNative 似乎也被成功调用(通过返回值验证),但对 data_out 的所有修改都不会反映在 Unity 中。
bool PostprocessNative(const uint16_t* data_in, int width,
int height, uint16_t* data_out) {
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
data_out[x + y * width] = 10;
}
}
// Changing the return value here is correctly reflected in C#.
return false;
}
我希望 short[] 的所有值都是 10,但它们是调用 JNI 之前的值。
这是将 Unity 短裤数组传递到 C++ 进行修改的正确方法吗?
【问题讨论】:
-
可能是复制/粘贴错字,但您的
PostprocessNative()采用 data_out 并修改了 packed_out。 -
确保 width 和 height 从 Unity 一直正确传递到 C++。我会在 C++ 端添加一些
__android_log_print()以确保循环实际正在执行。 -
@AlexCohn 是的,这是一个错字。现已修复,谢谢!
-
@AlexCohn 我尝试对图像尺寸进行硬编码并得到相同的结果。我知道图像是传入的,因为如果我在 C++ 中迭代更大的边界,我会得到一个段错误。
-
虽然您的问题集中在 Java->C++->Java 转换上,但您是否考虑过 Java->Unity 转换可能有问题?是否可以绕过 JVM 直接与本机代码集成?
标签: c# android c++ unity3d java-native-interface