按参考呼叫问题 [英] Call by Reference problem

查看:100
本文介绍了按参考呼叫问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用如下函数获取连接字符串和提供者名称:



 MyDriver * GetDSNAndProvider( const 字符串* sName,字符串 * sDSN,字符串 * sProvider)
{
if 1
{
sDSN = Data Source =(local); Initial Catalog = labops; User Id = labops; Password = 99w1ldf1re; ;
sProvider = System.Data.SqlClient;
MyDriver * myIface = new SQlClientDriver();
return myIface;
}
else
{
return NULL;
}
}







这是我的主要()



  int  _tmain( int  argc,_TCHAR * argv [])
{


String * sDQN,* sProvider;
尝试
{
MyDriver * MDriverIface = GetDSNAndProvider( < span class =code-string> sqlServer,sDQN,sProvider);
Console :: Write( String :: Concat( Provider Name,sProvider));
}
}





我将提供者名称视为null,我们如何通过引用进行此调用在c ++ .net。我正在使用公共语言运行时支持,旧语法(/clr:oldSyntax)\".

解决方案

来编译此代码。这看起来像C ++ / CLI。



1.你的gc对象需要帽子,例如。 ^。

2.您传递的指针值与引用值不同。

3.您无法将新指针返回到oracle接口。



我创建了两个MyDriver实现的模拟来验证它的工作原理。我假设一个C ++类而不是一个ref类。我注意到SQL服务器名称中的拼写错误。



  #include     stdafx.h 
#include < stddef.h >
#include < string.h >

使用 命名空间系统;

struct MyDriver
{
int common;
public
virtual const char * whoami() const = 0 ;
};

struct SQlClientDriver:MyDriver
{
int SQL;
public
const char * whoami() const { return SQL; }
};

struct OracleClientDriver:MyDriver
{
int 神谕;
public
const char * whoami() const { return Oracle; }
};

MyDriver * GetDSNAndProvider( String ^ sName, String ^& sDSN, String ^& sProvider)
{
if (sName == sqlServer
{
sDSN = Data Source =(local); Initial Catalog = myDb; User Id = user; Password = pw;;
sProvider = System.Data.SqlClient;
return new SQlClientDriver(); // 类定义在那里
}
else if (sName == Oracle
{
sDSN = 数据源=(本地);初始目录= myOracleDB;用户ID =用户;密码PW =;;
sProvider = System.Data.SqlClient;
return new OracleClientDriver(); // 类定义在那里
}
return NULL;
}

int main(array< system :: string xmlns:system = #unknown> ^ args)
{
Console :: WriteLine(L 正在开始......);
String ^ sDQN,^ sProvider;

MyDriver * MDriverIface = GetDSNAndProvider( sqlServer,sDQN,sProvider) ;
Console :: WriteLine( Provider Name {0},sProvider);
if (MDriverIface!= NULL)
{
const < span class =code-keyword> char
* whoami = MDriverIface-> whoami();
IntPtr pass =( IntPtr )const_cast< char>(whoami);
String ^ marshal = System :: Runtime :: InteropServices :: Marshal :: PtrToStringAnsi(pass,strlen(whoami));
Console :: WriteLine(marshal);
}

Console :: WriteLine(L 完成。);
Console :: ReadLine();
return 0 ;
}
< / char>< / system :: string>< /string.h>< /stddef.h>





我故意省略了try / catch以使错误更明显。


为什么不检查和处理这种情况:



  if (sProvider ==  null 
{
sProvider = my fallback;
}





正如Tomas所写:您的方法需要提供者名称sql server,但您将其作为sqlServer传递 !!! :-O


I am trying to get connection string and provider name using a function like this:

MyDriver* GetDSNAndProvider(const String* sName,String *sDSN,String *sProvider)
{
    if(1)
    {
        sDSN="Data Source=(local);Initial Catalog=labops;User Id=labops;      Password=99w1ldf1re;";
        sProvider="System.Data.SqlClient";
        MyDriver *myIface = new SQlClientDriver();
       return myIface;
    }
    else
    {
        return NULL;
    }
}




and this is my Main()

int _tmain(int argc, _TCHAR* argv[])
{
	

	String *sDQN,*sProvider;
	try
    {
	MyDriver *MDriverIface=GetDSNAndProvider("sqlServer",sDQN,sProvider);
        Console::Write(String::Concat("Provider Name ",   sProvider));
    }
}



I am getting the provider name as null, How we can do this call by reference in c++.net. I am compiling this code using "Common Language Runtime Support, Old Syntax (/clr:oldSyntax)".

解决方案

This looks like C++/CLI.

1. Your gc objects need hats eg. "^".
2. you're passing pointer values which are not the same as references.
3. you fail to return the new pointer to the oracle interface.

I created a mock of the two MyDriver implementations to verify it works. I'm assuming a C++ class and not a ref class. I noticed the typo in the SQL server name.

#include "stdafx.h"
#include <stddef.h>
#include <string.h>

using namespace System;

struct MyDriver
{
	int common;
public:
	virtual const char *whoami() const = 0;
};

struct SQlClientDriver : MyDriver
{
	int sql;
public:
	const char *whoami() const { return "SQL"; }
};

struct OracleClientDriver : MyDriver
{
	int oracle;
public:
	const char *whoami() const { return "Oracle"; }
};

MyDriver* GetDSNAndProvider(String^ sName, String ^ &sDSN, String ^ &sProvider)
{
    if(sName == "sqlServer")
    {
		sDSN="Data Source=(local);Initial Catalog=myDb;User Id=user;Password=pw;";
		sProvider="System.Data.SqlClient";
		return new SQlClientDriver();//class is defined there
	}
	else if (sName == "Oracle")
	{
		sDSN="Data Source=(local);Initial Catalog=myOracleDB;User Id=user;Password=pw;";
		sProvider="System.Data.SqlClient";
		return new OracleClientDriver();//class is defined there
	}
	return NULL;
}

int main(array<system::string xmlns:system="#unknown"> ^args)
{
    Console::WriteLine(L"Starting ...");
    String^ sDQN, ^sProvider;

    MyDriver *MDriverIface = GetDSNAndProvider("sqlServer",sDQN,sProvider);
    Console::WriteLine("Provider Name {0}", sProvider);
    if (MDriverIface != NULL)
    {
        const char *whoami = MDriverIface->whoami();
        IntPtr pass = (IntPtr)const_cast<char>(whoami);
        String^ marshal = System::Runtime::InteropServices::Marshal::PtrToStringAnsi(pass, strlen(whoami));
        Console::WriteLine(marshal);
    }

    Console::WriteLine(L"Done.");
    Console::ReadLine();
    return 0;
}
</char></system::string></string.h></stddef.h>



I purposely omitted the try/catch to make errors more obvious.


why dont you check and handle that case:

if( sProvider == null)
{
  sProvider = "my fallback";
}



And as Tomas wrote: Your method expects provider name "sql server" but you are passing it as "sqlServer".!!! :-O


这篇关于按参考呼叫问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆