Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Calling a C++ dll from COBOL.

Status
Not open for further replies.

shester1452

Programmer
Oct 22, 2007
8
US
Hi all. I am new to the forum. I have posted this in the COBOL forum, but thought I would try here too. I have run into a situation I could really use some help with. I have a legacy app written in Fujitsu COBOL that I am trying to call a c++ dll. When I try to execute the app I get the error message "The application failed to initialize properly(0x00000005)." I believe the problem is in the dll, but I don't know what the problem might be. Any help would be greatly appreciated.

Thanks.

Steve
 
When you say old, how old? I have V3. I could find out but if yours is newer than V3 then I probably won't be able to help.
 
Are you referring to the version of Visual Studio? If so it is v7.1.
 
No - which version of Cobol. I've got V3.
 
That's quite new. I'm just wondering: is it anything to do with the different versions of .net? You may need a config file to tell it which libraries to use with your app.

Do you have a machine with just .net 1.1 installed? If it works on that but not on any other, then it is definitely a config file problem.

The other thing is how are the parameters being passed to C++? Is it by value, by pointer, by reference or some other method.
 
I am doing other calls using c linkage in the same cobol app.

Here is my call to the dll.

CALL "bint" WITH C LINKAGE
USING BY VALUE WS-PIN-ENCRYPT
RETURNING WS-PIN-DECRYPT
END-CALL.

I really think the problem is in the C code b/c I have used the above call many times to other C dll's.

Here is the C source code. Maybe you can see something wrong there.

// This is the main DLL file.

#include "stdlib.h"
#include "stdio.h"
#include "stdafx.h"
#include "Bridge.h"



extern "C" {
#include <string.h>
}


#using "dotNetAssembly\bin\dotNetAssembly.dll"

using namespace System;
using namespace dotNetAssembly;


extern "C"
{

__declspec(dllexport) char * decrypt_pin(char *input)
{

String __gc *managed_input = new String(input);

mcDotNetClass __gc *DotNetObject;

DotNetObject = new mcDotNetClass;
System::Diagnostics::Debugger::Log(1, "Made it past new", "Made it past new");

char tmp __gc[] = System::Text::Encoding::UTF8->GetBytes(DotNetObject->DecryptPin(input));
char __pin *value = &tmp[0];

//strncpy(input, value, 4); //Max pin size should be 4

return value;

}

__declspec(dllexport) int Done(char *input, char *output)
{
try
{

String __gc *managed_input = new String(input);

mcDotNetClass __gc *DotNetObject;

DotNetObject = new mcDotNetClass;
System::Diagnostics::Debugger::Log(1, "Made it past new", "Made it past new");

char tmp __gc[] = System::Text::Encoding::UTF8->GetBytes(DotNetObject->DecryptPin(input));
char __pin *value = &tmp[0];

strncpy(output, value, tmp->Length); //Max pin size should be 4
return tmp->Length;
}
catch (...)
{
return 0;
}

}
__declspec(dllexport) int bint(int input)
{

mcDotNetClass __gc *DotNetObject;

DotNetObject = new mcDotNetClass;

return DotNetObject->test_integer(input);

}

__declspec(dllexport) char * bst(char *input, int buflen)
{

String __gc *managed_input = new String(input);

mcDotNetClass __gc *DotNetObject;

DotNetObject = new mcDotNetClass;

char tmp __gc[] = System::Text::Encoding::UTF8->GetBytes(DotNetObject->test_string(input));
char __pin *value = &tmp[0];

strncpy(input, value, buflen);

return input;

}

__declspec(dllexport) int barr(int *values, int len)
{

int i, cnt;
Array __gc *managed_values;
mcDotNetClass __gc *DotNetObject;

managed_values = Array::CreateInstance(__typeof(System::Int32),len);
cnt = managed_values->GetLength(0);


for (i=0;i < cnt;i++) {
managed_values->SetValue(__box(values), i);
}

DotNetObject = new mcDotNetClass;

return DotNetObject->test_array(managed_values);
}

}
 
Think maybe you ought to try it with unmanaged code first.
Try something like
Code:
__declspec(dllexport) int bint(int input)
{
    return input + 1;

 }
If that works, then try
Code:
__declspec(dllexport) int bint(int input)
{

    mcDotNetClass __gc *DotNetObject;

    DotNetObject = new mcDotNetClass;

    return input + 1;

}
Are you able to step into the code with the debugger?
 
I tried both of the examples you provided. When I try to run the debugger I get the error "The application failed to initialize properly(0x00000005). The specified file is not an executable program." So, I never even get to the code in debug.
 
In that case it is a config file problem. Only problem is I haven't done this for over a year and I don't have any examples handy. You'll have to google for this one.

You basically need some sort of xml config file to tell it that it is running .net 1.1 or something like that. Create the config file with the same name as the executable but with either a .cfg or .config extension, I can't remember which.

Your solution is somewhere along those lines.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top