We help IT Professionals succeed at work.

Compile problems with function that accepts FAR* params

jourdain_casale
on
879 Views
Last Modified: 2012-06-09
When I try to compile I get the error:
cannot convert parameter 1 from 'CHAR *__w64  []' to 'ExchNamePtr'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

The strange part is it only happens in the case where I call the function like this:

void broken(type parm1, type parm2, type parm3) {
    function(&parm1,&parm2,&parm3);
}
broken('string1','string2','string3');

But if I do it this way it is fine:

void works () {
     type parm1 = "string";
     type parm2 = "string";
     type parm3 = "string";
    function(&parm1,&parm2,&parm3);
}
works();

Does it make any sense if the typedefs used are exactly the same it just just passed through my function to cause this?
Comment
Watch Question

Should it be

broken("string1","string2","string3");

instead of

broken('string1','string2','string3');

Dennis

Author

Commented:
My actual program had double quotes, my example wasn't 100% accurate so that isn't the issue for this one.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Could you be a *bit* more precise about the types you are using?
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
BTW, 'type' as in

 type parm1 = "string";

Author

Commented:
The param types from the input side are declared like this:

typedef char first_type[11];

and the ones on the other side of the function are pointers to the type that should be passed:

i.e. the first type, and first param would have a typedef like this:

typesef first_type FAR * first_type_ptr;

The functions I'm using are from a 3rd party DLL and all I have is the .h file to look at to know what the function is expecting.
The following example works fine...... Is your problem similar to this ? whats "type" here? a class or something else ?

#include <iostream>
#include <string>

using namespace std;


class MyClass {
        string m_Name;
public :
        MyClass(const char* aStr);
};

MyClass::MyClass(const char *aStr):m_Name(aStr)
{
}

typedef MyClass type;

void function(type *ptr1, type *ptr2, type *ptr3)
{
}

void broken(type parm1, type parm2, type parm3) {
    function(&parm1,&parm2,&parm3);
}

void works () {
     type parm1 = "string";
     type parm2 = "string";
     type parm3 = "string";
    function(&parm1,&parm2,&parm3);
}

int main()
{
        works();
        broken("string1", "string2", "string3");

        return 0;
}
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Well, 'FAR' is quite obsloete these days. What *exactly* is that type and what is the exact function signature? Without that, we're just guessing here.

Author

Commented:
These are the actual typedefs:

typedef CHAR     ExchNameStr[11];
typedef CHAR     ConNameStr[11];
typedef CHAR     ConDateStr[51];

These are the typedefs for the method:

typedef ConNameStr   FAR *ContractNamePtr;
typedef ConDateStr   FAR *ContractDatePtr;
typedef CurrencyStr  FAR *CurrNamePtr;

Then there is this guy defining the actual function:
typedef INT  (WINAPI * lp_ptGetContractByName)(ExchNamePtr ExchangeName, ContractNamePtr ContractName, ContractDatePtr ContractDate, ContractStructPtr Contract);

If you map this into my example, you should be on the same page as me and see the issue.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Thank you. Well, in this case, change

void broken(type parm1, type parm2, type parm3) {
   function(&parm1,&parm2,&parm3);
}
broken('string1','string2','string3');


to

void broken(type parm1, type parm2, type parm3) {
   function(parm1,parm2,parm3);
}
broken('string1','string2','string3');

since using '&' on an array to get the address is incorrect - it makes it like passing a 'ExchNameStr**', which is not what you want. An array's address is given by it's name. A pitfall in this context.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Sorry ;o)

void broken(type parm1, type parm2, type parm3) {
  function(parm1,parm2,parm3);
}
broken("string1","string2","string3");

of course....

Author

Commented:
This is what it says on compile with that change. I tried a a few different changes to how I passed the data around and was only ever able to change the error message text, but not get rid of the error.

c:\Documents and Settings\jour\My Documents\Visual Studio Projects\simple\simple.cpp(751): error C2664: 'INT (ExchNamePtr,ContractNamePtr,ContractDatePtr,ContractStructPtr)' : cannot convert parameter 3 from 'CHAR []' to 'ContractDatePtr'
c:\Documents and Settings\jour\My Documents\Visual Studio Projects\simple\simple.cpp(751): error C2664: 'INT (ExchNamePtr,ContractNamePtr,ContractDatePtr,ContractStructPtr)' : cannot convert parameter 2 from 'CHAR []' to 'ContractNamePtr'
c:\Documents and Settings\jour\My Documents\Visual Studio Projects\simple\simple.cpp(751): error C2664: 'INT (ExchNamePtr,ContractNamePtr,ContractDatePtr,ContractStructPtr)' : cannot convert parameter 1 from 'CHAR []' to 'ExchNamePtr'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Could you post your exact code? From here, it seems that

void broken(type parm1, type parm2, type parm3) {
 function((ExchNamePtr)parm1,(ContractNamePtr)parm2,(ContractDatePtr)parm3);
}
broken("string1","string2","string3");

could work. Actually, your compiler should supply that conversion, but...

Author

Commented:
PS: There is $1,100 in Katrina red cross support in this if you can help solve this (I read your profile).

This is the basic stuff:

void pt_get_contract_param(ExchNameStr exchange_name, ConNameStr contract_name, ConDateStr contract_date) {
      ContractStruct  contract;
      ptGetContractByName(exchange_name,contract_name,contract_date,&contract));
}

void main() {
      pt_get_contract_param("abc123","abc123","abc123");
}
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
I think I got it. You should not use string literals here. Does

void pt_get_contract_param(ExchNameStr exchange_name, ConNameStr contract_name, ConDateStr contract_date) {
    ContractStruct  contract;
    ptGetContractByName(exchange_name,contract_name,contract_date,&contract));
}

void main() {

ExchNameStr ex = "abc123";
ConNameStr con = "abc123";
ConDateStr date = "abc123";

    pt_get_contract_param(ex,con,date);
}

work?

Author

Commented:
I tried this during the troubleshooting earlier, it gets the same error message on compile:

c:\Documents and Settings\jour\My Documents\Visual Studio Projects\simple\simple.cpp(751): error C2664: 'INT (ExchNamePtr,ContractNamePtr,ContractDatePtr,ContractStructPtr)' : cannot convert parameter 3 from 'CHAR []' to 'ContractDatePtr'
c:\Documents and Settings\jour\My Documents\Visual Studio Projects\simple\simple.cpp(751): error C2664: 'INT (ExchNamePtr,ContractNamePtr,ContractDatePtr,ContractStructPtr)' : cannot convert parameter 2 from 'CHAR []' to 'ContractNamePtr'
c:\Documents and Settings\jour\My Documents\Visual Studio Projects\simple\simple.cpp(751): error C2664: 'INT (ExchNamePtr,ContractNamePtr,ContractDatePtr,ContractStructPtr)' : cannot convert parameter 1 from 'CHAR []' to 'ExchNamePtr'
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:

#include <windows.h>

typedef CHAR     ExchNameStr[11];
typedef CHAR     ConNameStr[11];
typedef CHAR     ConDateStr[51];
typedef CHAR     CurrencyStr[51];

typedef ConNameStr   FAR *ContractNamePtr;
typedef ConDateStr   FAR *ContractDatePtr;
typedef CurrencyStr  FAR *CurrNamePtr;
typedef ExchNameStr  FAR* ExchNamePtr;

struct ContractStruct { int dummy;};

typedef ContractStruct  FAR* ContractStructPtr;


typedef INT  (WINAPI * lp_ptGetContractByName)(ExchNamePtr ExchangeName, ContractNamePtr ContractName, ContractDatePtr ContractDate, ContractStructPtr Contract);

lp_ptGetContractByName ptGetContractByName;

void pt_get_contract_param(ExchNameStr exchange_name, ConNameStr contract_name, ConDateStr contract_date) {
    ContractStruct  contract;
    ptGetContractByName((ExchNamePtr)&exchange_name,(ContractNamePtr)&contract_name,(ContractDatePtr)&contract_date,&contract);
}

void main() {
    pt_get_contract_param("abc123","abc123","abc123");
}

?

(compiles here, had to use some tricks, though ;o)

Author

Commented:
I'm using Visual C++ 2002, is it a special flag in the representation handling?
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Well, I am more familiar with VC6 and .NET 2003 - what problems does 2002 give?

Author

Commented:
It gives the errors I cut and pasted about converting paramaters...
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Have you tried the code from my last post above? It does compile, checked that with VC++.

Author

Commented:
I'm missed that, your program compiles perfectly. Now I'm really stuck.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Hm, if you apply the the changes to your actual code, does it run OK also? As I said, "Actually, your compiler should supply that conversion, but..."
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
And, it is mandantory to not use string literals in that case :o)
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
Ooops, let me correct the above:

#include <windows.h>

typedef CHAR     ExchNameStr[11];
typedef CHAR     ConNameStr[11];
typedef CHAR     ConDateStr[51];
typedef CHAR     CurrencyStr[51];

typedef ConNameStr   FAR *ContractNamePtr;
typedef ConDateStr   FAR *ContractDatePtr;
typedef CurrencyStr  FAR *CurrNamePtr;
typedef ExchNameStr  FAR* ExchNamePtr;

struct ContractStruct { int dummy;};

typedef ContractStruct  FAR* ContractStructPtr;


typedef INT  (WINAPI * lp_ptGetContractByName)(ExchNamePtr ExchangeName, ContractNamePtr ContractName, ContractDatePtr ContractDate, ContractStructPtr Contract);

lp_ptGetContractByName ptGetContractByName;

void pt_get_contract_param(ExchNameStr exchange_name, ConNameStr contract_name, ConDateStr contract_date) {
    ContractStruct  contract;
    ptGetContractByName((ExchNamePtr)&exchange_name,(ContractNamePtr)&contract_name,(ContractDatePtr)&contract_date,&contract);
}

void main() {

ExchNameStr ex = "abc123";
ConNameStr con = "abc123";
ConDateStr date = "abc123";

   pt_get_contract_param(ex,con,date);
}

Using a literal might lead to runtime errors, and since the functions takes addresses of buffers it could try to overwrite them, causing an access violation.

Author

Commented:
It only works if I put the string definitions inside my pt_get_contract_param subroutine. If I do it anywhere else or try and pass the values anywhere else it crashes, but this doesn't appear to be an issue in your program and I don't understand why.
CERTIFIED EXPERT
Top Expert 2012
Commented:
Unlock this solution and get a sample of our free trial.
(No credit card required)
UNLOCK SOLUTION

Author

Commented:
Ahhh, now I see it and it compiles now :-) I'm off to the red cross web site now.
jkr
CERTIFIED EXPERT
Top Expert 2012

Commented:
One *big* thank you!

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a sample view!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.