Java crashes when calling dll function using JNA - dll

I'm using JNA to run a dll function:
Here is all the code corresponding to that manner:
The Native Declarations:
//how the method declared
H264_Login (char *sIP, unsigned short wPort, char *sUserName, char *sPassword, LP_DEVICEINFO lpDeviceInfo, int *error, ,SocketStyle socketTyle=TCPSOCKET); // where LP_DEVICEINFO is a struct
//how the struct declared
typedef struct _H264_DVR_DEVICEINFO
{
SDK_SYSTEM_TIME tmBuildTime; // the "SDK_SYSTEM_TIME" is another struct
char sSerialNumber[64];
int byChanNum;
unsigned int uiDeviceRunTime;
SDK_DeviceType deviceTye; // the "SDK_DeviceType" is a enum
}H264_DVR_DEVICEINFO,*LP_DEVICEINFO;
// this is how "SDK_SYSTEM_TIME" is defined
typedef struct SDK_SYSTEM_TIME{
int year;
int month;
int day;
}SDK_SYSTEM_TIME;
// this is how "SDK_DeviceType" is defined
enum SDK_DeviceType
{
SDK_DEVICE_TYPE_DVR,
SDK_DEVICE_TYPE_MVR,
SDK_DEVICE_TYPE_NR
};
// this is how "SocketStyle" is defined
enum SocketStyle
{
TCPSOCKET=0,
UDPSOCKET,
SOCKETNR
};
The following is their corresponding Java mappings:
public class Test implements StdCallLibrary {
public interface simpleDLL extends StdCallLibrary {
long H264_Login(String sIP, short wPort, String sUserName, String sPassword,
Structure DeviceDate, int error, int TCPSOCKET);
}
static
{
System.loadLibrary("NetSdk");
}
// the struct implementation
public static class DeviceDate extends Structure{
public SDK_SYSTEM_TIME tmBuildTime;
public String sSerialNumber;
public IntByReference byChanNum;
public IntByReference uiDeviceRunTime;
public IntByReference deviceTpye;
#Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("tmBuildTime");
list.add("sSerialNumber");
list.add("byChanNum");
list.add("uiDeviceRunTime");
list.add("deviceTpye");
return list;
}
}
public static class SDK_SYSTEM_TIME extends Structure{
public IntByReference year;
public IntByReference month;
public IntByReference day;
#Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("year");
list.add("month");
list.add("day");
return list;
}
}
// and then how I called it through the main function
public static void main(String args[]) throws FileNotFoundException{
simpleDLL INSTANCE = (simpleDLL) Native.loadLibrary( ("NetSdk"), simpleDLL.class);
DeviceDate dev = new DeviceDate() // where DeviceDate is a static class inherits com.sun.jna.Structure
int err = (int) INSTANCE.H264_GetLastError();
long result = INSTANCE.H264_Login("255.255.255.255", (short) 33333, "admin", "admin", dev, err, 0);
}
}
upon running the app, the Java crashes:
and this is the full problem signature:
Problem signature:
Problem Event Name: APPCRASH
Application Name: javaw.exe
Application Version: 7.0.600.19
Application Timestamp: 536a95c6
Fault Module Name: jna3976113557901128571.dll
Fault Module Version: 4.0.0.215
Fault Module Timestamp: 52d3949a
Exception Code: c0000005
Exception Offset: 0000e3a2 OS
Version: 6.1.7601.2.1.0.256.1
Locale ID: 1033
Additional Information 1: 7bc2
Additional Information 2: 7bc24d73a5063367529b81d28aecc01c
Additional Information 3: 5bea
Additional Information 4: 5beaa1c0441c3adb156a170a61c93d19
Read our privacy statement online:
http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0409
If the online privacy statement is not available, please read our
privacy statement offline: C:\Windows\system32\en-US\erofflps.txt

Your mappings have a number of errors. Your structures should look like the following (IntByReference represents places where you would pass the address of an int, and you can't substitute String for a primitive native char array). Please refer to the JNA mapping documentation to ensure you understand how native types map to Java types:
public static class LP_DEVICE_INFO extends Structure{
public SDK_SYSTEM_TIME tmBuildTime;
public byte[] sSerialNumber = new byte[64];
public int byChanNum;
public int uiDeviceRunTime;
public int deviceType; // Assuming the size of the enum is int
#Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("tmBuildTime");
list.add("sSerialNumber");
list.add("byChanNum");
list.add("uiDeviceRunTime");
list.add("deviceTpye");
return list;
}
}
public static class SDK_SYSTEM_TIME extends Structure{
public int year;
public int month;
public int day;
#Override
protected List<Object> getFieldOrder() {
List<Object> list = new ArrayList<>();
list.add("year");
list.add("month");
list.add("day");
return list;
}
}

Related

I want a class A to use a method of class B, and I want a method of class A be used by class B

I'm doing a little project for school where I try to do a spreadsheet program, and I have two classes, I will be simplifying this with pseudocode a little bit so it's not too messy.
class DocumentController {
Document doc // This is a class with a CRUD on a document (It haves
// Sheets and every Sheet haves a Table full of Cells)
Parser p
getValueOfCell (sheetName, positionX, positionY) {
returns value of a cell in a sheet in the position x,y
}
setCell (String expression, sheetName, positionX, positionY) {
//Somewhere here we need to use p.evaluate()
}
}
class Parser {
DocumentController docController;
evaluate (expression: String) {
//Somewhere here, I need to use method getCell from Document
// for evaluating the expression (The expressions have
// references to other cells so the Parser need to resolve
// these references)
...
return value of the expression (float, integer, string, whatever)
}
}
So apparently my teacher said to me that this is a bad design, because these classes are too coupled and this is a code smell. Can someone explain me why is this so bad? How can I make a better design?
Thank you, sorry if I made some typos or the code is not legible
I think you want something like:
Class Main{
public void main(){
DocumentController dc = new DocumentController();
//you can get ahold of the parser by
Parser p = dc.getParser();
}
}
Class Parser{
DocumentController dc;
public Parser(DocumentController dc){
this.dc = dc;
}
//your methods
}
Class DocumentController{
Parser p;
public DocumentController(){
this.p = new Parser(this);
}
public Parser getParser(){
return this.p;
}
//your methods
}
Although there are probably better ways of doing this instead like passing your object to the method when you need it. Something like
Class Main{
public void main(){
DocumentController dc = new DocumentController();
Parser p = new Parser();
p.myParserMethod(dc);
dc.myDocMethod(p);
}
}
Class Parser{
public myParserMethod(DocumentController dc){
//you can use the same documentController object here
}
}
Class DocumentController{
public myDocMethod(Parser p){
//you can use your parser object here
}
}
hope that helps
It looks like you want to format value by some key expression. If yes, then we can create mapping between this key expression and format classes. Then we can use Factory pattern to create desired objects to format your cell value.
Let me show a simple example via C#.
So this is a DocumentController:
public class DocumentController
{
private DocumentService _documentService;
public DocumentController()
{
_documentService = new DocumentService(); // this dependency can be
// resolved by IoC container
}
public void GetValueCell(int docId, string sheetName, int positionX,
int positionY)
{
_documentService.GetValueCell(docId, sheetName, positionX,
positionY);
}
public void SetCell(int docId, string expression, string sheetName, int
positionX, int positionY, object value)
{
_documentService.SetCell(docId, expression, sheetName, positionX,
positionY, value);
}
}
And this is a service which will execute logic related to Document:
public class DocumentService
{
private DocumentRepository _documentRepository;
public DocumentService()
{
_documentRepository = new DocumentRepository();
}
public string GetValueCell(int docId, string sheetName, int positionX, int positionY)
{
Document document = _documentRepository.GetById(docId);
return document.GetCellValue(sheetName, positionX, positionY);
}
public void SetCell(int docId, string expression, string sheetName, int
positionX, int positionY, object value)
{
Document document = _documentRepository.GetById(docId);
document.SetCellValue(expression, sheetName, positionX, positionY,
value);
}
}
It is unknown how you get Document, but it is possible to use repository pattern for that purpose.
public class DocumentRepository
{
public Document GetById(int id) { throw new NotImplementedException(); }
}
and this is a Document class:
public class Document
{
private object[][] _cells;
public Document(int x)
{
_cells = new object[x][];
}
public string GetCellValue(string sheetName, int positionX, int positionY)
{
return string.Empty;
}
public void SetCellValue(string expression, string sheetName, int
positionX, int positionY, object value)
{
FormatterType formatterType = new
FormatterTypeToExpression().FormatterByExpression[expression];
Formatter formatter = new FormatterFactory().
FormatterByFormatterType[formatterType];
object formattedCell = formatter.Format(value);
_cells[positionX][positionY] = formattedCell;
}
}
and this is a mapping between FormatterType and your key expression:
public class FormatterTypeToExpression
{
public Dictionary<string, FormatterType> FormatterByExpression { get; set; } =
new Dictionary<string, FormatterType>
{
{ "string", FormatterType.String}
// here you write expressions and foramtters
};
}
This is a formatter type:
public enum FormatterType
{
String, Number, Decimal, Whatever
}
Then you need something like factory to take a formatter:
public abstract class Formatter
{
public abstract object Format(object value);
}
And abstract class which will define behavior of derived formatter classes:
public class FormatterString : Formatter
{
public override object Format(object value)
{
return "I am a formatted string value";
}
}
An example how FormatterFactory could look like:
public class FormatterFactory
{
public Dictionary<FormatterType, Formatter> FormatterByFormatterType { get; set; }
= new Dictionary<FormatterType, Formatter>
{
{ FormatterType.String, new FormatterString()}
// here you write FormatterType and formatters
};
}

Setter methods do not work whereas Getter methods work fine

The error is always that the dino cannot be converted into type string
however im struggling to understand why the compiler would think of trying to
converting dino into ints or strings from the first method
public static void Tyrannosaurus()
{
String DinoName = Name();
Dinosaur Tyrannosaurus = new Dinosaur();
Tyrannosaurus.name = DinoName;
Tyrannosaurus = setDiet(Tyrannosaurus, DinoDiet[0]);
Tyrannosaurus = setHP(Tyrannosaurus, 100);
Tyrannosaurus = setDamage(Tyrannosaurus, 200);
DaysLoop(DinoName);
return;
}
Here is the first getter method being used for the Dinosaur record and Tyrannosaurus instance above
public static String getName (Dinosaur dino)
{
return Tyrannosaurus.name;
}
public static String getDiet (Dinosaur dino)
{
return Tyrannosaurus.diet;
}
public static int getHP (Dinosaur dino)
{
return dino.HP;
}
public static int getDamage (Dinosaur dino)
{
return dino.damage;
}
setter method which does not work is done from here, I do see in other java setters people use this. but I havent quite grasped that concept yet
public static String setDiet (Dinosaur dino, String TyranDiet)
{
dino.diet = TyranDiet;
return dino;
}
public static int setHP (Dinosaur dino, int TyranHP)
{
dino.HP = TyranHP;
return dino;
}
public static int setDamage (Dinosaur dino, int TyranDamage)
{
dino.damage = TyranDamage;
return dino;
}
//////////////////////////////////
You return dino as string and dino as an int in below methods.
public static String setDiet (Dinosaur dino, String TyranDiet);
public static int setHP (Dinosaur dino, int TyranHP);
public static int setDamage (Dinosaur dino, int TyranDamage);
that's why its pops error like that
basically setters not returns anything. remove return and re-write code like this
public static void setDiet (Dinosaur dino, String TyranDiet)
{
dino.diet = TyranDiet;
}
public static void setHP (Dinosaur dino, int TyranHP)
{
dino.HP = TyranHP;
}
public static void setDamage (Dinosaur dino, int TyranDamage)
{
dino.damage = TyranDamage;
}

No converter found capable of converting from type [java.lang.String] to type [org.springframework.data.solr.core.geo.Point]

I am trying to use spring-data-solr in order to access to my Solr instance through my Spring boot application. I have the following bean class:
#SolrDocument(solrCoreName = "associations")
public class Association implements PlusimpleEntityI {
#Id
#Indexed
private String id;
#Indexed
private String name;
#Indexed
private Point location;
#Indexed
private String description;
#Indexed
private Set<String> tags;
#Indexed
private Set<String> topics;
#Indexed
private Set<String> professionals;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Point getLocation() {
return location;
}
public void setLocation(Point location) {
this.location = location;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<String> getTags() {
return tags;
}
public void setTags(Set<String> tags) {
this.tags = tags;
}
public Set<String> getTopics() {
return topics;
}
public void setTopics(Set<String> topics) {
this.topics = topics;
}
public Set<String> getProfessionals() {
return professionals;
}
public void setProfessionals(Set<String> professionals) {
this.professionals = professionals;
}
}
I have implemented the following repository in order to access to the related information:
public interface AssociationsRepository extends SolrCrudRepository<Association, String> {
}
I have created a configuration class which looks like the following one:
#Configuration
#EnableSolrRepositories(basePackages = {"com.package.repositories"}, multicoreSupport = true)
public class SolrRepositoryConfig {
#Value("${solr.url}")
private String solrHost;
#Bean
public SolrConverter solrConverter() {
MappingSolrConverter solrConverter = new MappingSolrConverter(new SimpleSolrMappingContext());
solrConverter.setCustomConversions(new CustomConversions(null));
return solrConverter;
}
#Bean
public SolrClientFactory solrClientFactory () throws Exception {
return new MulticoreSolrClientFactory(solrClient());
}
#Bean
public SolrClient solrClient() throws Exception {
return new HttpSolrClient.Builder(solrHost).build();
}
#Bean
public SolrOperations associationsTemplate() throws Exception {
SolrTemplate solrTemplate = new SolrTemplate(solrClient());
solrTemplate.setSolrConverter(solrConverter());
return solrTemplate;
}
}
Unfortunately, when I try to read an association from my Solr instance I got the following error:
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [org.springframework.data.solr.core.geo.Point]
I don't understand why it is not able to find a converter if I have explicitly defined it in the solrTemplate() method.
This is my POM definition:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
Thank you for your help.
EDIT:
I've also tried with different BUILD-RELEASEs but they are highly unstable and I've found a lot of errors using them.
Alessandro, as you can see directly in the GeoConverters class on GitHub, the implemented converters are only for:
org.springframework.data.geo.Point
and not for:
org.springframework.data.solr.core.geo.Point
Simply use this class and you don't even need a custom converter for this. Spring Data for Solr will perform the conversion for you.
I'm using a slightly patched version of the 3.0.0 M4, but I'm pretty sure this solution should apply seamlessly also to your case.

JNA complex union structure mapping

In JNA,how to map a complex union structure from follows c codes:
typedef struct {
char *vmxSpec;
char *serverName;
char *thumbPrint;
long privateUse;
VixDiskLibCredType credType;//enum type
union VixDiskLibCreds {
struct VixDiskLibUidPasswdCreds {
char *userName;
char *password;
} uid;
struct VixDiskLibSessionIdCreds {
char *cookie;
char *userName;
char *key;
} sessionId;
struct VixDiskLibTicketIdCreds *ticketId;
} creds;
uint32 port;
} VixDiskLibConnectParams;
when i mapping the struct,it throws a NullPointerException:
Exception in thread "Thread-56" java.lang.NullPointerException
at java.util.ComparableTimSort.countRunAndMakeAscending(ComparableTimSort.java:290)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:157)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
at com.sun.jna.Structure.sort(Structure.java:889)
at com.sun.jna.Structure.getFields(Structure.java:921)
at com.sun.jna.Structure.deriveLayout(Structure.java:1054)
at com.sun.jna.Structure.calculateSize(Structure.java:978)
at com.sun.jna.Structure.calculateSize(Structure.java:945)
at com.sun.jna.Structure.allocateMemory(Structure.java:375)
at com.sun.jna.Structure.<init>(Structure.java:184)
at com.sun.jna.Structure.<init>(Structure.java:172)
at com.sun.jna.Structure.<init>(Structure.java:159)
at com.sun.jna.Structure.<init>(Structure.java:151)
at com.test.vmm.vdp.VixDiskLibrary$VixDiskLibConnectParams.<init>(VixDiskLibrary.java:71)
at com.test.vmm.vdp.VixDiskLibrary$VixDiskLibConnectParams$ByReference.<init>(VixDiskLibrary.java:72)
at com.test.vmm.vdp.VixDiskLib.run(VixDiskLib.java:47)
at java.lang.Thread.run(Thread.java:744)
my code as follows:
public static class VixDiskLibConnectParams extends Structure {
public static class ByReference extends VixDiskLibConnectParams implements Structure.ByReference {}
public static class ByValue extends VixDiskLibConnectParams implements Structure.ByValue {}
public static class VixDiskLibCreds extends Union {
public static class ByReference extends VixDiskLibCreds implements Structure.ByReference {}
public static class ByValue extends VixDiskLibCreds implements Structure.ByValue {}
public VixDiskLibUidPasswdCreds uid;
public VixDiskLibSessionIdCreds sessionId;
public VixDiskLibTicketIdCreds.ByReference ticketId;
public static class VixDiskLibUidPasswdCreds extends Structure {
public static class ByReference extends VixDiskLibUidPasswdCreds implements Structure.ByReference {}
public String userName;
public String password;
protected List getFieldOrder() {
List list = new ArrayList();
list.add(userName);
list.add(password);
return list;
}
}
public static class VixDiskLibSessionIdCreds extends Structure {
public static class ByReference extends VixDiskLibSessionIdCreds implements Structure.ByReference {}
public String cookie;
public String userName;
public String key;
protected List getFieldOrder() {
List list = new ArrayList();
list.add(cookie);
list.add(userName);
list.add(key);
return list;
}
}
public static class VixDiskLibTicketIdCreds extends Structure {
public static class ByReference extends VixDiskLibUidPasswdCreds implements Structure.ByReference {}
protected List getFieldOrder() {
List list = new ArrayList();
return list;
}
}
protected List getFieldOrder() {
List list = new ArrayList();
list.add(uid);
list.add(sessionId);
list.add(ticketId);
return list;
}
}
public String vmxSpec;
public String serverName;
public String thumbPrint;
public NativeLong privateUse;
public int credType;
public VixDiskLibCreds.ByValue creds;
public int port;
public void read() {
super.read();
switch (credType) {
case VixDiskLibCredType.VIXDISKLIB_CRED_UID:
creds.setType(VixDiskLibCreds.VixDiskLibUidPasswdCreds.class);
creds.read();
break;
case VixDiskLibCredType.VIXDISKLIB_CRED_SESSIONID:
creds.setType(VixDiskLibCreds.VixDiskLibSessionIdCreds.class);
creds.read();
break;
case VixDiskLibCredType.VIXDISKLIB_CRED_TICKETID:
creds.setType(VixDiskLibCreds.VixDiskLibTicketIdCreds.class);
creds.read();
break;
case VixDiskLibCredType.VIXDISKLIB_CRED_SSPI:
System.out.println("VixDiskLibCredType : VIXDISKLIB_CRED_SSPI");
break;
default:
System.out.println("VixDiskLibCredType : unknow");
break;
}
}
protected List getFieldOrder() {
List list = new ArrayList();
list.add(vmxSpec);
list.add(serverName);
list.add(thumbPrint);
list.add(privateUse);
list.add(credType);
list.add(creds);
list.add(port);
return list;
}
}
what's wrong?A clear explanation on how to do it will be better.
Thanks
i have found the problem, quotes are forgotten in the method add() when called to add element by List
The correct code will be:
protected List getFieldOrder() {
List list = new ArrayList();
list.add("userName");
list.add("password");
return list;
}

Jackson configuration to write enum as object

When I try to serialize and deserialize a Set<ClassA<?>> of generic objects that look as follows:
public class ClassA<T> {
private ClassB datum;
private T value;
...
}
If that T happens to be an enum, it gets written as a String value. This is fine for serialization, but when I deserialize, it's not possible to know if the String value is an enum or not. Jackson then turns the resulting object into a String and you get a ClassA<String> instead of ClassA<SomeEnumType>.
Is there a configuration in Jackson to have it create some hints that the value is an enum? Or perhaps turn the enum into a JSON object rather then a string value?
Is there a configuration in Jackson to have it create some hints that the value is an enum?
It's possible to deserialize to an enum instance from a matching JSON string value. Or is this somehow not applicable to your situation?
Here is an example.
import java.util.Set;
import java.util.TreeSet;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.type.TypeFactory;
public class JacksonFoo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
String myEnumJson = mapper.writeValueAsString(MyEnum.MyEnum1);
System.out.println(myEnumJson);
MyEnum myEnum = mapper.readValue(myEnumJson, MyEnum.class);
System.out.println(myEnum);
Set<ClassA<MyEnum>> set = new TreeSet<ClassA<MyEnum>>();
set.add(new ClassA<MyEnum>(new ClassB("bValue7"), MyEnum.MyEnum1));
set.add(new ClassA<MyEnum>(new ClassB("bValue8"), MyEnum.MyEnum2));
String setJson = mapper.writeValueAsString(set);
System.out.println(setJson);
TypeFactory typeFactory = TypeFactory.defaultInstance();
Set<ClassA<MyEnum>> setCopy = mapper.readValue(setJson,
typeFactory.constructCollectionType(Set.class,
typeFactory.constructParametricType(ClassA.class, MyEnum.class)));
System.out.println(setCopy);
}
}
class ClassA<T> implements Comparable<ClassA<T>>
{
ClassB datum;
T value;
ClassA()
{
}
ClassA(ClassB datum, T value)
{
this.datum = datum;
this.value = value;
}
#Override
public int compareTo(ClassA<T> o)
{
return 42;
}
#Override
public String toString()
{
return String.format("ClassA: datum=%s, value=%s", datum, value);
}
}
class ClassB
{
String bValue;
ClassB()
{
}
ClassB(String bValue)
{
this.bValue = bValue;
}
#Override
public String toString()
{
return String.format("ClassB: bValue=%s", bValue);
}
}
enum MyEnum
{
MyEnum1("myEnum1", 1), MyEnum2("myEnum2", 2);
String name;
int id;
MyEnum(String name, int id)
{
this.name = name;
this.id = id;
}
}
Output:
"MyEnum1"
MyEnum1
[{"datum":{"bValue":"bValue7"},"value":"MyEnum1"},{"datum":{"bValue":"bValue8"},"value":"MyEnum2"}]
[ClassA: datum=ClassB: bValue=bValue7, value=MyEnum1, ClassA: datum=ClassB: bValue=bValue8, value=MyEnum2]
If for some reason it's necessary to have enums serialized as POJOs, then it appears custom serialization processing is required. Serializing enums with Jackson