By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,587 Members | 1,891 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,587 IT Pros & Developers. It's quick & easy.

Passing byte array from c# to unmanaged c++ and vise versa

P: 1
I am trying to create a Java to .Net interop and the way I am doing it is by creating a C# com object and a native unmanaged c++ dll that uses JNIEnv of java.
the java is loading the native c++ dll and invokes a method in it which invokes a method on

The command passed from java to .Net is a byte array and the response passed back is also a byte array

the C# managed COM object which finally invokes a method on a regular C# managed dll.
My C# com object code is as follows:
(I am not showing all code, only relevent sections)
************************************************** ************
public class CommandExecutor : ICommandExecutor
{
public byte[] ExecuteCommand(byte[] command)
{
return MyStaticClass.ExecuteCommand(command);
}
}
************************************************** ************
MyStaticClass is a static class that executes the given command in a managed referenced C#

dll.

My C++ code is:
************************************************** ************
JNIEXPORT jbyteArray JNICALL

Java_com_gigaspaces_serialization_pbs_commands_Dis patcher_executeCommand
(JNIEnv *env, jobject obj, jbyteArray jstr)
{

jboolean iscopy;
jbyteArray answerArray = 0;
SAFEARRAY *psaOut = 0;
SAFEARRAY *psa;
jbyte* pBuff;

int len = env->GetArrayLength(jstr);
pBuff = env->GetByteArrayElements(jstr,&iscopy);
pBuff[len]=0;

SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = len;

psa = SafeArrayCreate(VT_UI1,1,rgsabound);

for (long i=0; i < len; i++)
SafeArrayPutElement(psa,&i,(void *)&pBuff[i]);

pServicePtr->ExecuteCommand( psa, &psaOut);

if(psaOut != 0)
{
len = psaOut->rgsabound[0].cElements;
answerArray = env->NewByteArray(len);

env->SetByteArrayRegion(answerArray, 0, len, (jbyte*)psaOut->pvData);


}

env->ReleaseByteArrayElements(jstr, pBuff, 0);
SafeArrayDestroy(psa);

return answerArray;
}
************************************************** ************
pServicePtr points to an instance of the C# com object.

The java loads the dll containing this c++ code and use the native mechanizm to invoke the

method through JNI.

the java code is like this:
************************************************** ************
public static ByteArrayInputStream execute(ByteArrayOutputStream output)
{
byte[] inputBuffer = executeCommand(output.toByteArray());
// If null is returned a serious error happened on delegator side
if (inputBuffer == null)
throw new RuntimeException(
"Unexpected error happend on delegator side, see delegators

log for more information");
ByteArrayInputStream input = new ByteArrayInputStream(inputBuffer);

return input;
}

private static native byte[] executeCommand(byte[] command);
************************************************** ************
This solution seems to work fine however in an unconsistent way the JVM crashes sometimes with

the following error (Not showing the entire dump)
************************************************** ************
#
# An unexpected error has been detected by HotSpot Virtual Machine:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7c93426d, pid=1340, tid=7144
#
# Java VM: Java HotSpot(TM) Server VM (1.5.0_12-b04 mixed mode)
# Problematic frame:
# C [ntdll.dll+0x3426d]
#

--------------- T H R E A D ---------------

Current thread (0x00880740): JavaThread "LRMI Connection--pool-1-thread-13" daemon

[_thread_in_vm, id=7144]

siginfo: ExceptionCode=0xc0000005, reading address 0x00000000

Registers:
EAX=0x00000000, EBX=0x00000100, ECX=0x045452c8, EDX=0x00000000
ESP=0x0657f4a4, EBP=0x0657f6c4, ESI=0x04541c38, EDI=0x04544ac0
EIP=0x7c93426d, EFLAGS=0x00010246

Top of Stack: (sp=0x0657f4a4)
0x0657f4a4: 00002e7f 00002e80 00880740 00000000
0x0657f4b4: 0657f938 00b12d15 00000000 0657f93c
0x0657f4c4: 00000001 0657f940 0657f944 0657f508
0x0657f4d4: 0657f948 0657f94c 0657f90c 00881c54
0x0657f4e4: 00881c50 0657f910 0657f914 0657f6b4
0x0657f4f4: 00881c40 00881c44 00000b00 00880740
0x0657f504: 101daf00 03fb5008 6db4169d 0657f6b4
0x0657f514: 00cdc9f0 6daf3dce 00cdad48 0657f950

Instructions: (pc=0x7c93426d)
0x7c93425d: 11 89 95 64 ff ff ff 8b 40 0c 89 85 5c ff ff ff
0x7c93426d: 8b 00 3b 42 04 0f 85 13 01 00 00 3b c1 0f 85 0b


Stack: [0x06540000,0x06580000), sp=0x0657f4a4, free space=253k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [ntdll.dll+0x3426d]
C [msvcrt.dll+0x1c3c9]
C [msvcrt.dll+0x1c3e7]
C [msvcrt.dll+0x1c42e]
V [jvm.dll+0x21de76]
C [JNetBridgeCpp.dll+0x12f0]
C [JNetBridgeCpp.dll+0x1133]
j com.gigaspaces.serialization.pbs.commands.Dispatch er.executeCommand([B)[B+0
j com.gigaspaces.serialization.pbs.commands.Dispatch er.a(Ljava/io/ByteArrayOutputStream;)

Ljava/io/ByteArrayInputStream;+4
j com.j_spaces.obf.mb.a(ILjava/util/List;)V+13

************************************************** ************
It seems as if I have some kind of a memory override (maybe a leak but it doesn't seem like an

out of memory exception) maybe in the C++ dll.

Can anyone help? I am stuck!!!
Thoughts I have are:
-Who is incharge of freeing the memory of the byte[] returned by the C# com object, the COM object or the C++ dll? Anyhow I tried to call SafeArrayDestroy(psaOut); and it didn't help
-What happens if the C# garbage collector decide to move the byte[] returned by execute command location in the memory while the C++ dll is still using it? Can I pin memory allocation on return values?

JNetBridgeCpp.dll is my CPP dll
Dec 26 '07 #1
Share this question for a faster answer!
Share on Google+

Post your reply

Sign in to post your reply or Sign up for a free account.