Skip to content

Commit 9b57b0c

Browse files
committed
fix: resolve Native pointer is null by fixing constructor flow and JNI linkage
1 parent 8ad48a4 commit 9b57b0c

2 files changed

Lines changed: 21 additions & 28 deletions

File tree

binding/src/main/java/dev/eatgrapes/live2d/CubismUserModel.java

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,12 @@ public class CubismUserModel extends Native {
66
private Consumer<String> motionFinishedCallback;
77

88
public CubismUserModel() {
9-
super(0);
10-
this.establishNative();
9+
super(createNative());
10+
linkNative();
1111
}
1212

13-
private void establishNative() {
14-
try {
15-
java.lang.reflect.Field f = Native.class.getDeclaredField("_ptr");
16-
f.setAccessible(true);
17-
f.set(this, createNative());
18-
} catch (Exception e) {
19-
throw new RuntimeException(e);
20-
}
21-
}
22-
23-
private native long createNative();
13+
private static native long createNative();
14+
private native void linkNative();
2415

2516
public void loadModel(byte[] buffer) { loadModelNative(_ptr, buffer); }
2617
private static native void loadModelNative(long ptr, byte[] buffer);
@@ -79,4 +70,4 @@ private void onMotionFinished(String name) {
7970
@Override
8071
public void close() { deleteNative(_ptr); }
8172
private static native void deleteNative(long ptr);
82-
}
73+
}

native/src/CubismUserModel_JNI.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ using namespace Live2D::Cubism::Framework::Rendering;
1313

1414
class JniUserModel : public CubismUserModel {
1515
public:
16-
JniUserModel(JNIEnv* env, jobject javaObj) {
16+
JniUserModel(JNIEnv* env) {
1717
env->GetJavaVM(&_jvm);
18-
_javaObj = env->NewGlobalRef(javaObj);
18+
}
19+
20+
void link(JNIEnv* env, jobject obj) {
21+
_javaObj = env->NewGlobalRef(obj);
1922
}
2023

2124
~JniUserModel() {
@@ -43,15 +46,12 @@ class JniUserModel : public CubismUserModel {
4346
std::vector<csmByte> motionBuf(buffer, buffer + size);
4447
auto* motion = CubismMotion::Create(motionBuf.data(), (csmSizeInt)motionBuf.size());
4548
if (!motion) return;
46-
4749
_motionBuffers[motion] = std::move(motionBuf);
48-
4950
motion->SetFinishedMotionHandlerAndMotionCustomData([](ACubismMotion* self) {
5051
auto* m = static_cast<CubismMotion*>(self);
5152
auto* model = static_cast<JniUserModel*>(m->GetFinishedMotionCustomData());
5253
model->queueFinishedMotion(m);
5354
}, this);
54-
5555
_motionManager->StartMotionPriority(motion, true, priority);
5656
}
5757

@@ -62,7 +62,6 @@ class JniUserModel : public CubismUserModel {
6262

6363
void update(float dt) {
6464
if (!_model) return;
65-
6665
{
6766
std::lock_guard<std::mutex> lock(_pendingMutex);
6867
for (auto* m : _pendingDeletion) {
@@ -72,12 +71,10 @@ class JniUserModel : public CubismUserModel {
7271
}
7372
_pendingDeletion.clear();
7473
}
75-
7674
_model->LoadParameters();
7775
_motionManager->UpdateMotion(_model, dt);
7876
_model->SaveParameters();
7977
if (_pose) _pose->UpdateParameters(_model, dt);
80-
8178
if (_dragManager) {
8279
_dragManager->Update(dt);
8380
auto* idm = CubismFramework::GetIdManager();
@@ -86,7 +83,6 @@ class JniUserModel : public CubismUserModel {
8683
_model->AddParameterValue(idm->GetId("ParamEyeBallX"), _dragManager->GetX());
8784
_model->AddParameterValue(idm->GetId("ParamEyeBallY"), _dragManager->GetY());
8885
}
89-
9086
if (_physics) _physics->Evaluate(_model, dt);
9187
_model->Update();
9288
}
@@ -112,9 +108,8 @@ class JniUserModel : public CubismUserModel {
112108
if (_jvm->GetEnv((void**)&env, JNI_VERSION_1_6) == JNI_EDETACHED) _jvm->AttachCurrentThread((void**)&env, nullptr);
113109
return env;
114110
}
115-
116111
JavaVM* _jvm;
117-
jobject _javaObj;
112+
jobject _javaObj = nullptr;
118113
std::vector<csmByte> _mocBuffer, _physicsBuffer, _poseBuffer;
119114
std::map<CubismMotion*, std::vector<csmByte>> _motionBuffers;
120115
std::vector<CubismMotion*> _pendingDeletion;
@@ -123,8 +118,15 @@ class JniUserModel : public CubismUserModel {
123118

124119
extern "C" {
125120

126-
JNIEXPORT jlong JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_createNative(JNIEnv* env, jobject thiz) {
127-
return (jlong) new JniUserModel(env, thiz);
121+
JNIEXPORT jlong JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_createNative(JNIEnv* env, jclass) {
122+
return (jlong) new JniUserModel(env);
123+
}
124+
125+
JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_linkNative(JNIEnv* env, jobject thiz) {
126+
jclass cls = env->GetObjectClass(thiz);
127+
jfieldID fid = env->GetFieldID(cls, "_ptr", "J");
128+
jlong ptr = env->GetLongField(thiz, fid);
129+
((JniUserModel*)ptr)->link(env, thiz);
128130
}
129131

130132
JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_deleteNative(JNIEnv*, jclass, jlong ptr) {
@@ -226,4 +228,4 @@ JNIEXPORT void JNICALL Java_dev_eatgrapes_live2d_CubismUserModel_drawNative(JNIE
226228
env->ReleaseFloatArrayElements(matrix, m_ptr, JNI_ABORT);
227229
}
228230

229-
}
231+
}

0 commit comments

Comments
 (0)