-
Notifications
You must be signed in to change notification settings - Fork 476
How to bind native libraries
kdw9502 edited this page Dec 7, 2020
·
4 revisions
Some companies(especially game company) uses C/C++ more than java. They uses the native libraries for communication between clients and servers.
They don’t know Java much which nGrinder is built on and want to reuse existing their native asset as much as possible.
nGrinder has been shipped with JNA which enables java and native libraries(so, jar) binding. Therefore users can use DLL or SO files in their scripts.
The followings describes the step necessary to run so or dlls with nGrinder.
- Prepare the DLLs or SOs which defines the simple functions which can be easily bridged to Java.
Methods with no parameter is pefered. If you want to pass the parameter from nGrinder script to DLLs or SOs, please make the parameter type simple as much as possible like char* or int. - Upload the created DLLs or SOs into lib folder. If you will define the script in the helloworld/TestRunner.groovy, you should upload those native libraries in the helloworld/lib/ folder.
- Write the test script using JNA binding. Following show the simple binding between the groovy script and native lib named “native_client”
package org.ngrinder;
// import JNA
import com.sun.jna.Library
import com.sun.jna.Native
import static net.grinder.script.Grinder.grinder
import net.grinder.plugin.http.HTTPRequest
import net.grinder.plugin.http.HTTPPluginControl;
import net.grinder.script.GTest
import net.grinder.script.Grinder
import net.grinder.scriptengine.groovy.junit.GrinderRunner
import net.grinder.scriptengine.groovy.junit.annotation.BeforeProcess
import net.grinder.scriptengine.groovy.junit.annotation.BeforeThread
// import static net.grinder.util.GrinderUtils.* // You can use this if you're using nGrinder after 3.2.3
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Test
import org.junit.runner.RunWith
import HTTPClient.HTTPResponse
import HTTPClient.NVPair
@RunWith(GrinderRunner)
class TestRunner {
// Define the interface which native library has.
interface NativeClient extends Library {
public void connect()
// String will converted to char pointer
public void connect(String ip, int port)
}
public static GTest test
public static HTTPRequest request
public static def nativeClient;
@BeforeProcess
public static void beforeProcess() {
// load 'native_client.so or native_client.dll with interface NativeClient
//(File extension(so or dll) is depending on agent's OS)
nativeClient = Native.loadLibrary( 'native_client', NativeClient);
test = new GTest(1, "Test1")
}
@BeforeThread
public void beforeThread() {
grinder.statistics.delayReports=true;
// Record the current test instances method "doTest"
// because the nativeClient instance is not recordable because it's the native method.
test.record(this, "doTest");
}
@Test
public void test(){
doTest()
}
public void doTest() {
// Call the native library's methods.
nativeClient.connect();
}
}
- In Jython's case, Write the test script using ctypes binding. Following show the simple binding between the jython script and native lib named "native_client"
from net.grinder.script.Grinder import grinder
from net.grinder.script import Test
import ctypes
test = Test(1, "Test1")
class TestRunner:
# initlialize a thread
def __init__(self):
test.record(TestRunner.__call__)
grinder.statistics.delayReports=True
def before(self):
# load 'native_client.so or native_client.dll with interface NativeClient
# (File extension(so or dll) is depending on agent's OS)
# Note that path contains lib/, Unlike Groovy's case.
self.native_client = ctypes.cdll.LoadLibrary("lib/native_client.dll")
# if the method has parameters, you need to assign list of argument type
self.native_client.Connect.argtypes = [ctypes.c_char_p, ctypes.c_int]
# test method
def __call__(self):
self.before()
self.native_client.Connect("10.30.220.18", 31001)
- Then run the test.
Please be aware that you should run the SOs or DLLs in the machines which contains same library version(e.x. GLIBC) when you developed those.