按参考呼叫问题 [英] Call by Reference problem
本文介绍了按参考呼叫问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试使用如下函数获取连接字符串和提供者名称:
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屋!
查看全文