I have created a DLL using Visual C++ 2008 that creates two external functions. Using python I have created two separate executable functions to run these. When using PowerBuilder to call the function, the first executable runs fine. The second executable results in a runtime error: error calling external function %s
. I use a .def
file and have the correct ordinals for each function. Any advice?
The function declarations in C are as follows (sorry they are quite long):
extern "C" int __stdcall start_proctor( double points[], double weights[], double opoints[], double &SG, char sg_estimated[], double &smooth, char ptitle[], double &pheight, double &pwidth, char save_location[], int &show, int &ZV, char roundM[], char roundD[], int &zoom, char cwd[], int &x_scale_major_tick,int &y_scale_major_tick, char points_of[], char points_color[], char points_type[], int &points_size, char curve_of[], char curve_color[], int &curve_alpha, int &curve_size, char grid_of[], char grid_color[], int &grid_alpha, int &grid_x_dash, int &grid_y_dash, char opt_of[], char opt_color[], int &opt_alpha, int &opt_x_dash, int &opt_y_dash, int &x_scale_major_tick_c, int &y_scale_major_tick_c, char points_of_c[], char points_color_c[], char points_type_c[], int &points_size_c, char curve_of_c[], char curve_color_c[], int &curve_alpha_c, int &curve_size_c, char grid_of_c[], char grid_color_c[], int &grid_alpha_c, int &grid_x_dash_c, int &grid_y_dash_c, char opt_of_c[], char opt_color_c[], int &opt_alpha_c, int &opt_x_dash_c, int &opt_y_dash_c, int &return_default, int &splash, double &optmoisture, double &maxdd, double &percent_oversized, double &o_SG , double &o_moisture, double &o_optmoisture, double &o_maxdd, int &oversized_flag, int &debug, char c_output[] );
extern "C" int __stdcall start_grain_size( char dsn_name[], char userID[], char passwd[], double test_data[], int &td_length, double upper_bound[], int &ub_length, double lower_bound[], int &lb_length, char envelope[], char specification[], char pointmarker[], char splinemarker[], char display[], char scale[], char units[], char xlabel[], char direction[], char maximum_density_line[], int &pan, char title[], char save_location[], char cwd[], int &show, double &width, double &height, char output[] );
In powerbuilder the external function declarations are:
Function int start_proctor(ref double points[3,8], ref double weigthts[8], ref double opoints[3,8], ref double sg, ref string sg_estimated, ref double smooth, ref string ptitle, ref double pheight, ref double pwidth, ref string save_location, ref int show, ref int zv, ref string roundm, ref string roundd, ref int zoom, ref string cwd, ref int li_x_scale_major_tic, ref int li_y_scale_major_tic, ref string ls_points_of, ref string ls_points_color, ref string ls_points_type, ref int li_points_size, ref string ls_curve_of, ref string ls_curve_color, ref int li_curve_alpha, ref int li_curve_siz开发者_如何学运维e, ref string ls_grid_of, ref string ls_grid_color, ref int li_grid_alpha, ref int li_grid_x_dash, ref int li_grid_y_dash, ref string ls_opt_of, ref string ls_opt_color, ref int li_opt_alpha, ref int li_opt_x_dash, ref int li_opt_y_dash, ref int li_x_scale_major_tic_t, ref int li_y_scale_major_tic_t, ref string ls_points_of_t, ref string ls_points_color_t, ref string ls_points_type_t, ref int li_points_size_t, ref string ls_curve_of_t, ref string ls_curve_color_t, ref int li_curve_alpha_t, ref int li_curve_size_t, ref string ls_grid_of_t, ref string ls_grid_color_t, ref int li_grid_alpha_t, ref int li_grid_x_dash_t, ref int li_grid_y_dash_t, ref string ls_opt_of_t, ref string ls_opt_color_t, ref int li_opt_alpha_t, ref int li_opt_x_dash_t, ref int li_opt_y_dash_t, ref int li_return_default, ref int li_splash, ref double optmoisture, ref double maxdd, ref double pover, ref double osg, ref double om, ref double o_optmoisture, ref double o_maxdd, ref int oversized_flag, ref int debug_flag, ref string output) LIBRARY "ELMTREE_EXTERNAL.dll" ALIAS FOR "start_proctor;ansi"
Function int start_grain_size(ref string dsn_name, ref string userid, ref string passwd, ref double test_data[], ref int td_length, ref double upper_bound[], ref int ub_length, ref double lower_bound[], ref int lb_length, ref string envelope, ref string specification, ref string pointmarker, ref string splinemarker, ref string display, ref string scale, ref string units, ref string xlabel, ref string direction, ref string maximum_density_line, ref int pan, ref string title, ref string save_location, ref string cwd, ref int show, ref double width, ref double height, ref string output) LIBRARY "ELMTREE_EXTERNAL.dll" ALIAS FOR "start_grain_size;ansi"
start_grain_size results in the error
I don't see anything wrong with the PB code. I think your error is in the C code that's calling Python. You may not be setting the name of the function you want to invoke correctly. That's what the %s in the error message suggests. I tagged this question for python-c-api to try to attract a few gurus. They will doubtless want to see your C code that's calling Python.
I'm going to try a wild guess (not really enough information yet to be sure), and say that the PB app is having difficulty locating the DLL in question. You can confirm this by using Process Monitor to watch your PB app (make sure you set the filter so that the Process Name matches your app, or you'll get a flood of info, although you can filter after the fact) and watch for any failures accessing the DLL on the failure case. It could be something like a current directory is being changed, and location of the DLL had been depending on that link in the search chain.
If that is the case, I'd recommend creating an App Path for your application, which includes the path of your application, even if it is only the folder containing your EXE. IME, it has solved problems like these.
Good luck,
Terry.
精彩评论