accessing decorated function names in a DLL #1318
Replies: 1 comment 2 replies
-
I'll give a fairly comprehensive answer to this, as it is a topic that might be generally useful to others in future. The function names are essentially passive, so the only really failure mode possible with those is that you get the exported name wrong and Dolphin can't find it. That isn't the case here, as you've got the exported name right (e.g. by running dumpbin/exports on the DLL). The "decorated" names that you are seeing are just the conventions for stdcall exports, i.e. leading underscore and FANN_EXTERNAL struct fann *FANN_API fann_create_sparse(float connection_rate, unsigned int num_layers, ...) Getting the calling convention wrong is another common error, and may result in Dolphin crashing altogether (stack faults are generally not recoverable). Also not the case here. Assuming you built the fannfloat DLL in Win32 configuration from the VS2010 solution in libfann/fann, then I can see that stdcall is the correct convention for all the exported functions aside from the 3x varargs functions and one data export. Some possible reasons for memory faults are:
For the first, a correct invocation might look something like this: ann := FANNStruct new.
"Initialize fields of `ann` appropriately here"
input := FLOAT new value: 1.23; yourself.
desired_output := FLOAT newPointer.
FANNLibrary default fann_train: ann input: input desired_output: desired_output. For the 2nd, the structure layout can be tricky for large structures. I often build IDL and type libraries for large APIs so that I can get an auto-generated first level API wrapper to avoid errors hand building the projection myself, but that in itself can be a big investment of time and you have to be familiar with MIDL, so this may not be feasible. What I'd do as a quick check is to first compare the printf("sizeof(fann)=%d\n", sizeof(struct fann)); I then ran it, and it printed You can then compare the offsets against the field offsets in the structure (inspect it, or look at the accessor methods). You can always modify the For the 3rd issue you may be able to refer to existing examples to cross check that you are setting things up correctly. I often try and transcribe an existing sample so that I know what I am doing should work if I can just translate it correctly. However, creating a projection to any reasonably complex library can require abandoning treating the library like a black box, and instead dropping down into a low-level debugger and debugging through the library code. You at least have access to the source, and can build the library easily, so this is straightforward. Having verified all the structure layouts are correct, and that you are passing the correct argument types, if memory faults still occur then your next step is to run under the VisualStudio debugger. In the debug configuration of the FANN dll you are using, go into the the project configuration properties in VS and change the Debugging/Command to the filename of the dolphin launcher exe you are using. Then F5 and Dolphin should launch. Note that you will find Dolphin will occasionally generate memory faults internally to the VM because it uses reserved but uncommitted pages to manage dynamic growth of heap and stacks. You should start to recognise where these occur, and can just ignore them (i.e continue execution). If you now start running your faulting code, you should be able to catch the error and try and work back from there. If the fault fires in the FANN code you will hopefully be able to see what is not correctly set up. If the fault is due to corruption of Dolphin's heap, then building and run a debug VM may help. It may not be easy. Lastly, bear in mind that Dolphin's HTH Blair printf("sizeof(fann)=%d\n", sizeof(struct fann));
printf("offsetof(struct fann, errno_f) = %d\n", offsetof(struct fann, errno_f));
printf("offsetof(struct fann, error_log) = %d\n", offsetof(struct fann, error_log));
printf("offsetof(struct fann, errstr) = %d\n", offsetof(struct fann, errstr));
printf("offsetof(struct fann, learning_rate) = %d\n", offsetof(struct fann, learning_rate));
printf("offsetof(struct fann, learning_momentum) = %d\n", offsetof(struct fann, learning_momentum));
printf("offsetof(struct fann, connection_rate) = %d\n", offsetof(struct fann, connection_rate));
printf("offsetof(struct fann, network_type) = %d\n", offsetof(struct fann, network_type));
printf("offsetof(struct fann, first_layer) = %d\n", offsetof(struct fann, first_layer));
printf("offsetof(struct fann, last_layer) = %d\n", offsetof(struct fann, last_layer));
printf("offsetof(struct fann, total_neurons) = %d\n", offsetof(struct fann, total_neurons));
printf("offsetof(struct fann, num_input) = %d\n", offsetof(struct fann, num_input));
printf("offsetof(struct fann, num_output) = %d\n", offsetof(struct fann, num_output));
printf("offsetof(struct fann, weights) = %d\n", offsetof(struct fann, weights));
printf("offsetof(struct fann, connections) = %d\n", offsetof(struct fann, connections));
printf("offsetof(struct fann, train_errors) = %d\n", offsetof(struct fann, train_errors));
printf("offsetof(struct fann, training_algorithm) = %d\n", offsetof(struct fann, training_algorithm));
printf("offsetof(struct fann, total_connections) = %d\n", offsetof(struct fann, total_connections));
printf("offsetof(struct fann, output) = %d\n", offsetof(struct fann, output));
printf("offsetof(struct fann, num_MSE) = %d\n", offsetof(struct fann, num_MSE));
printf("offsetof(struct fann, MSE_value) = %d\n", offsetof(struct fann, MSE_value));
printf("offsetof(struct fann, num_bit_fail) = %d\n", offsetof(struct fann, num_bit_fail));
printf("offsetof(struct fann, bit_fail_limit) = %d\n", offsetof(struct fann, bit_fail_limit));
printf("offsetof(struct fann, train_error_function) = %d\n",
offsetof(struct fann, train_error_function));
printf("offsetof(struct fann, train_stop_function) = %d\n", offsetof(struct fann, train_stop_function));
printf("offsetof(struct fann, callback) = %d\n", offsetof(struct fann, callback));
printf("offsetof(struct fann, user_data) = %d\n", offsetof(struct fann, user_data));
printf("offsetof(struct fann, cascade_output_change_fraction) = %d\n",
offsetof(struct fann, cascade_output_change_fraction));
printf("offsetof(struct fann, cascade_output_stagnation_epochs) = %d\n",
offsetof(struct fann, cascade_output_stagnation_epochs));
printf("offsetof(struct fann, cascade_candidate_change_fraction) = %d\n",
offsetof(struct fann, cascade_candidate_change_fraction));
printf("offsetof(struct fann, cascade_candidate_stagnation_epochs) = %d\n",
offsetof(struct fann, cascade_candidate_stagnation_epochs));
printf("offsetof(struct fann, cascade_best_candidate) = %d\n",
offsetof(struct fann, cascade_best_candidate));
printf("offsetof(struct fann, cascade_candidate_limit) = %d\n",
offsetof(struct fann, cascade_candidate_limit));
printf("offsetof(struct fann, cascade_weight_multiplier) = %d\n",
offsetof(struct fann, cascade_weight_multiplier));
printf("offsetof(struct fann, cascade_max_out_epochs) = %d\n",
offsetof(struct fann, cascade_max_out_epochs));
printf("offsetof(struct fann, cascade_max_cand_epochs) = %d\n",
offsetof(struct fann, cascade_max_cand_epochs));
printf("offsetof(struct fann, cascade_min_out_epochs) = %d\n",
offsetof(struct fann, cascade_min_out_epochs));
printf("offsetof(struct fann, cascade_min_cand_epochs) = %d\n",
offsetof(struct fann, cascade_min_cand_epochs));
printf("offsetof(struct fann, cascade_activation_functions) = %d\n",
offsetof(struct fann, cascade_activation_functions));
printf("offsetof(struct fann, cascade_activation_functions_count) = %d\n",
offsetof(struct fann, cascade_activation_functions_count));
printf("offsetof(struct fann, cascade_activation_steepnesses) = %d\n",
offsetof(struct fann, cascade_activation_steepnesses));
printf("offsetof(struct fann, cascade_activation_steepnesses_count) = %d\n",
offsetof(struct fann, cascade_activation_steepnesses_count));
printf("offsetof(struct fann, cascade_num_candidate_groups) = %d\n",
offsetof(struct fann, cascade_num_candidate_groups));
printf("offsetof(struct fann, cascade_candidate_scores) = %d\n",
offsetof(struct fann, cascade_candidate_scores));
printf("offsetof(struct fann, total_neurons_allocated) = %d\n",
offsetof(struct fann, total_neurons_allocated));
printf("offsetof(struct fann, total_connections_allocated) = %d\n",
offsetof(struct fann, total_connections_allocated));
printf("offsetof(struct fann, quickprop_decay) = %d\n", offsetof(struct fann, quickprop_decay));
printf("offsetof(struct fann, quickprop_mu) = %d\n", offsetof(struct fann, quickprop_mu));
printf("offsetof(struct fann, rprop_increase_factor) = %d\n",
offsetof(struct fann, rprop_increase_factor));
printf("offsetof(struct fann, rprop_decrease_factor) = %d\n",
offsetof(struct fann, rprop_decrease_factor));
printf("offsetof(struct fann, rprop_delta_min) = %d\n", offsetof(struct fann, rprop_delta_min));
printf("offsetof(struct fann, rprop_delta_max) = %d\n", offsetof(struct fann, rprop_delta_max));
printf("offsetof(struct fann, rprop_delta_zero) = %d\n", offsetof(struct fann, rprop_delta_zero));
printf("offsetof(struct fann, sarprop_weight_decay_shift) = %d\n",
offsetof(struct fann, sarprop_weight_decay_shift));
printf("offsetof(struct fann, sarprop_step_error_threshold_factor) = %d\n",
offsetof(struct fann, sarprop_step_error_threshold_factor));
printf("offsetof(struct fann, sarprop_step_error_shift) = %d\n",
offsetof(struct fann, sarprop_step_error_shift));
printf("offsetof(struct fann, sarprop_temperature) = %d\n", offsetof(struct fann, sarprop_temperature));
printf("offsetof(struct fann, sarprop_epoch) = %d\n", offsetof(struct fann, sarprop_epoch));
printf("offsetof(struct fann, train_slopes) = %d\n", offsetof(struct fann, train_slopes));
printf("offsetof(struct fann, prev_steps) = %d\n", offsetof(struct fann, prev_steps));
printf("offsetof(struct fann, prev_train_slopes) = %d\n", offsetof(struct fann, prev_train_slopes));
printf("offsetof(struct fann, prev_weights_deltas) = %d\n", offsetof(struct fann, prev_weights_deltas));
printf("offsetof(struct fann, scale_mean_in) = %d\n", offsetof(struct fann, scale_mean_in));
printf("offsetof(struct fann, scale_deviation_in) = %d\n", offsetof(struct fann, scale_deviation_in));
printf("offsetof(struct fann, scale_new_min_in) = %d\n", offsetof(struct fann, scale_new_min_in));
printf("offsetof(struct fann, scale_factor_in) = %d\n", offsetof(struct fann, scale_factor_in));
printf("offsetof(struct fann, scale_mean_out) = %d\n", offsetof(struct fann, scale_mean_out));
printf("offsetof(struct fann, scale_deviation_out) = %d\n", offsetof(struct fann, scale_deviation_out));
printf("offsetof(struct fann, scale_new_min_out) = %d\n", offsetof(struct fann, scale_new_min_out));
printf("offsetof(struct fann, scale_factor_out) = %d\n", offsetof(struct fann, scale_factor_out)); Which gave me this output:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
I'm trying to interface with FANN library and create wrapper classes for it, using 'External Interfacing' topic under the Programming cookbook from the (really very useful) help file.
the FANN library functions are not consistent, some are decorated and some are not. trying to access the decorated functions like
<stdcall: void '_fann_train@12' FANNStruct* float* float*>
gives a memory access error/fault
the undecorated functions seems to work without errors.
i tried to search the given documentation and search the net but could not found a solution.
I assume I'm missing something simple and got confused midway. is there a way to call these functions or identify and resolve the issue?
thanks in advance for the support
Beta Was this translation helpful? Give feedback.
All reactions